perltcpserverhotdeploy

Perl Net::Server hot deployment


I am using Net::Server::Prefork to launch a TCP server. The startup routine looks like this:

use 5.10.1;
use strict;
use warnings;
use parent 'Net::Server::Fork';

        Dispatcher->run(
            'host'            => $host                                   || '*',
            'port'            => $port                                   || 7000,
            'ipv'             => '*',
            'log_level'       => $main::config{'backend.loglevel'}       || 0,
            'log_file'        => $main::config{'backend.logfile'}        || undef,
            'pid_file'        => $main::config{'backend.pidfile'}        || undef,
            'user'            => $main::config{'backend.user'}           || 'nobody',
            'group'           => $main::config{'backend.group'}          || 'nogroup',
            'max_servers'     => $main::config{'backend.maxconnections'} || 3,
            'background'      => !$main::config{'backend.foreground'}    || undef,
            'allow'           => $main::config{'ip'}                     || '.*',
            'reverse_lookups' => 1,
        );

Dispatcher uses this function to process requests:

sub process_request {
    eval {
        local $SIG{'ALRM'} = sub { die "Timed Out!\n" };
        my $previous_alarm = alarm($timeout);
        my @args;
        {
            my $command =  <STDIN>;
            @args = split /\s+/, $command;
            alarm($timeout);
        }

        alarm(($main::config{'timeout'} + 5) || 185);
        {
            Dispatcher::main(@args);
        }
        alarm($previous_alarm);
    };
};

Now this is all good and well. However, when updating the server, I currently have the problem that in order not to kill requests that are in the midst of being processed, I have to check for active processes and wait until they are finished with the additional problem that while waiting new clients could connect. So - is there a chance to 'phase out' running child processes, i.e. terminate idle preforked processes, replace them with new version, and replace each running (old) process with a new version once the old process finishes?

Alternatively, can I block incoming connections until all old child processes are finished and then restart the server as a whole? I was thinking about doing this with temporary firewall rules, but would really prefer having perl handle this.

Any ideas are appreciated!


Solution

  • Have you tried to use leave_children_open_on_hup configuration option and restart server using HUP signal? [recipe for linux/unix]
    It should work according to documentation.

    Net::Server Restarting