Я использую Net::Server::Prefork для запуска TCP-сервера. Процедура запуска выглядит следующим образом:
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,
);
Диспетчер использует эту функцию для обработки запросов:
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);
};
};
Теперь все хорошо и хорошо. Однако при обновлении сервера у меня в настоящее время возникает проблема, заключающаяся в том, что для того, чтобы не убивать запросы, которые находятся в процессе обработки, я должен проверять активные процессы и ждать их завершения с дополнительной проблемой, заключающейся в том, что при ожидании новых клиентов мог подключиться. Итак, есть ли шанс «поэтапно отказаться» от запущенных дочерних процессов, т. Е. Завершить бездействующие предварительно разветвленные процессы, заменить их новой версией и заменить каждый запущенный (старый) процесс новой версией после завершения старого процесса?
В качестве альтернативы, могу ли я заблокировать входящие соединения, пока все старые дочерние процессы не будут завершены, а затем перезапустить сервер в целом? Я думал о том, чтобы сделать это с помощью временных правил брандмауэра, но действительно предпочел бы, чтобы perl справился с этим.
Любые идеи приветствуются!