nysus has asked for the wisdom of the Perl Monks concerning the following question:

I'm looking into seeing how I can speed up my Rex tasks. Rex has a lot of startup overhead. Even out of the box, a very simple task that just prints "hi" to the command line can take 1/2 second locally. A Rexfile with lots of tasks and modules and submodule is taking around 2.5 seconds to run a task on my local machine.

I did some google and see the PPerl module, which didn't install and looks ancient. I see another called SpeedCGI which also look ancient. Before I went any further, I'd figure I'd check in with the Monks before I wasted any time with deadends. Thanks!

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

  • Comment on Recommendation for a persistent perl solution?

Replies are listed 'Best First'.
Re: Recommendation for a persistent perl solution?
by duelafn (Parson) on May 24, 2020 at 21:54 UTC

    I've recently done a couple projects writing D-Bus services. I've found them to be quite nice to use (once you get over the verbose connection strings). If you are on Linux, I'd suggest including D-Bus in your investigations.

    These projects were in python, so I can't comment on Net::DBus specifically, but it looks to be the thing to use.

    Some features: Is an RPC tool so using it is just calling methods, clients don't have to reconnect if your server process needs to restart, systemd integration means you can have your server process start on demand.

    Update Upon looking at Rex, I'm not sure my suggestion is quite reasonable. I expected you were running something where you could split the slow start pieces into a service which exposes callable methods. Rex seems to be able to run in a server mode itself, so I don't see why you wouldn't use that -- I must be fundamentally misunderstanding what Rex does or what you want... Sorry

    Good Day,
        Dean

      Thanks for sharing your advice. I have been talking to the lead developer. Though Rex doesn't out of the box run like a daemon, he says he has a method he uses that basically turns it into one by creating a task that waits for incoming requests. I'm going to investigate that route.

      I also created my own little hack that does some symlink/bash trickery that loads a different, pared-down Rexfile when local commands are run so the load time is improved. 1/2 second response isn't perfect, but I can live with it. It's much better than 2.5 seconds.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        Well, for fun I poked at Net::DBus, this will give you a service:

        use 5.020; use strict; use warnings; package My::Dog::Rex; use Net::DBus::Exporter qw(org.my.rex.Runner); use base qw(Net::DBus::Object); # use Rex -feature => [qw/1.4/]; dbus_method("walk_dog", [], []); sub walk_dog { my $self = shift; say "Walking the dog"; # user "root"; # password "ch4ngem3"; # # desc "Show system information"; # task "sysinfo", sub { # say run "uname -a"; # }; } 1; package My::Rex::Service; use base qw(Net::DBus::Service); sub new { my $class = shift; my $self = $class->SUPER::new(@_); My::Dog::Rex->new($self, "/my/dog/rex"); return $self; } package main; use Net::DBus; use Net::DBus::Reactor; my $bus = Net::DBus->session; my $rex = My::Rex::Service->new($bus, "org.my.rex"); Net::DBus::Reactor->main->run; exit 0;

        This is how you would trigger methods (from a separate script)

        use 5.020; use strict; use warnings; use Net::DBus; my $bus = Net::DBus->session; my $rex = $bus->get_service("org.my.rex")->get_object("/my/dog/rex"); $rex->walk_dog;

        And when you want to run on the system bus instead of the user's session bus, change all the ->session to ->system, add the following to "/etc/dbus-1/system.d/org.my.rex.conf" and then run "systemctl reload dbus.service"

        <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuratio +n 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.d +td"> <busconfig> <!-- Root can own or use the Rex service --> <policy user="root"> <allow own="org.my.rex"/> <allow send_destination="org.my.rex"/> <allow receive_sender="org.my.rex"/> </policy> <!-- Nobody else can do anything --> <policy context="default"> <deny send_destination="org.my.rex"/> <deny receive_sender="org.my.rex"/> </policy> </busconfig>

        Good Day,
            Dean

Re: Recommendation for a persistent perl solution?
by perlfan (Vicar) on May 26, 2020 at 00:24 UTC
    Some generate C code with B::C with a lot of stuff initialized in the BEGIN block, then compile it. I've only played with it so YMMV. What does this give you? Assuming your start up time is related to local initializations (variables, loading file contents, etc); then it'll allow you to compile an executable that has already done all the stuff you shove in BEGIN

    If the start up is due to network related things or truly dynamic things, then it that won't help you. You only option is to daemonize it. I can't recommend any from personal experience, but there are a few modules on metacpan to choose from for this. And if SpeedCGI is the same thing as speedy, then yes it is ancient and probably best to avoid.

    Another option that comes to mind is starman.