[Bio] / FigKernelScripts / run_rabbit_daemon_set.pl Repository:
ViewVC logotype

View of /FigKernelScripts/run_rabbit_daemon_set.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (download) (as text) (annotate)
Wed May 4 16:00:29 2011 UTC (8 years, 9 months ago) by olson
Branch: MAIN
CVS Tags: mgrast_dev_08112011, mgrast_dev_06072011, mgrast_dev_08022011, rast_rel_2014_0912, myrast_rel40, rast_rel_2014_0729, mgrast_dev_05262011, mgrast_release_3_1_2, mgrast_release_3_1_1, rast_rel_2011_0928, mgrast_version_3_2, mgrast_dev_12152011, mgrast_dev_10262011, mgrast_release_3_1_0, HEAD
Changes since 1.2: +0 -1 lines
remove debug

use strict;
use IO::Async::Loop;
use IO::Async::Timer::Countdown;
use IO::Async::Process;
use IO::Async::Signal;
use Time::HiRes 'gettimeofday';
use Data::Dumper;
use Log::Log4perl;
use Getopt::Long;

=head1 SYNOPSIS

  run_rabbit_daemon_set -n N -c log-conf -- [run_rabbit_daemon args]

=head1 DESCRIPTION

Run a set of N rabbit daemons. Set the environment
variable DAEMON_INDEX to the index of the daemon, so that
they can make logfiles appropriately.

=cut

my $usage = "$0 -n Nprocs -c logger-conf -- command args";

my $n = 1;
my $log_conf;

my $rc = GetOptions("n=i" => \$n,
		    "c=s" => \$log_conf);

($rc && @ARGV > 0) or die $usage;

if ($log_conf)
{
    Log::Log4perl->init($log_conf);
}

my $logger = Log::Log4perl->get_logger("run_daemons");

my $args = [@ARGV];

$logger->info("startup with nprocs=$n command=@ARGV");

my $loop = IO::Async::Loop->new();

my @active_children;
my @restarting_child;
my @child_loggers;

#
# On a SIGHUP we send a SIGTERM to the children to signal them to
# do a clean shutdown, and will then restart them automatically.
#

my $restart = IO::Async::Signal->new(name => "HUP",
				     on_receipt => \&restart_children);
$loop->add($restart);

for my $i (0..$n-1)
{
    $child_loggers[$i] = Log::Log4perl->get_logger("child_$i");
    start_child($i, $args);
}

$loop->loop_forever();

sub restart_children
{
    for my $idx (0..$n-1)
    {
	my $proc = $active_children[$idx];
	if ($proc)
	{
	    $logger->info("Sending TERM to " . $proc->pid);
	    kill("TERM", $proc->pid);
	    $restarting_child[$idx] = 1;
	}
    }
}

sub start_child
{
    my($idx, $args) = @_;

    my $logger = $child_loggers[$idx];
    $logger->info("Starting child $idx");

    my $now = gettimeofday;
    my $env = { %ENV };
    $env->{DAEMON_INDEX} = $idx;

    my $proc = IO::Async::Process->new(command => $args,
				       stdout => {
					   on_read => sub {
					       my($stream, $bufref) = @_;
					       handle_child_input($stream, $bufref, $idx);
					       return 0;
					   },
				       },
				       stderr => {
					   on_read => sub {
					       my($stream, $bufref) = @_;
					       handle_child_input($stream, $bufref, $idx);
					       return 0;
					   },
				       },
				       setup => [env => $env],
				       on_finish => sub {
					   my($proc, $rc)= @_;
					   handle_child_death($proc, $rc, $idx, $args, $now);
				       },
				      );
    $loop->add($proc);
    my $pid = $proc->pid;
    $active_children[$idx] = $proc;
    $logger->info("Started child $idx as $pid");
}

sub handle_child_input
{
    my($stream, $bufref, $idx) = @_;

    my $logger = $child_loggers[$idx];

    while ($$bufref =~ s/^(.*)\n//)
    {
	$logger->info($1);
    }
}

sub handle_child_death
{
    my($proc, $rc, $idx, $args, $start_time) = @_;
    my $elap = sprintf("%.3f", gettimeofday - $start_time);

    my $logger = $child_loggers[$idx];

    if ($rc == 0)
    {
	$logger->info("Child idx=$idx exited cleanly after $elap seconds");
	start_child($idx, $args);
    }
    elsif ($restarting_child[$idx])
    {
	$restarting_child[$idx] = 0;
	$logger->info("Child idx=$idx exited after restart after $elap seconds");
	start_child($idx, $args);
    }
    else
    {
	$logger->error("Child idx=$idx failed with rc=$rc after $elap seconds");
	my $timer = IO::Async::Timer::Countdown->new(delay => 10,
						     on_expire => sub { start_child($idx, $args); });
	$timer->start();
	$loop->add($timer);
	return;
    }
}
    
       

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3