Search code examples
perlmod-fcgid

How to restart Perl script running under mod_fcgid when changed?


I'm running some FastCGI scripts under mod_fcgid, and I'd like those to reload automatically whenever I make any changes to the script.

Under mod_fastcgi, you can configure

FastCgiConfig -autoUpdate

to do exactly that, but mod_fcgid doesn't have such an option. Anyone have a good workaround for this?

The best thing I came up with, is:

while (my $cgi = CGI::Fast->new()) {
    processRequest($cgi);
    exit if -M $0 < 0;  # restart if script changed
}

which exits after handling one more request. But this is not ideal, especially when there are multiple instances of the script running, it might take quite a while before all old instances had an opportunity to run once more and exit.

If I do the exit before processRequest, the user gets an error, so that won't do either.

Thanks in advance,

– Michael


Solution

  • The right way to do it is a little bit subtle. I would recommend looking at Plack::Loader::Restarter for how to do it, or better yet adapting you app to run on Plack and then just launching it with plackup's -r option to load the restarter automatically. Adapting your app might be easier than you expect, possibly as easy as changing

    use CGI::Fast;
    while (my $cgi = CGI::Fast->new) {
        processRequest($cgi);
    }
    

    to

    use CGI::Emulate::PSGI;
    use CGI;
    
    my $app = CGI::Emulate::PSGI->handler(sub {
        my $cgi = CGI->new;
        processRequest($cgi);
    });
    

    (writing a proper native PSGI app is even nicer, but this version saves you from rewriting most of your app).