[sf-perl] parallelize system tasks, collecting statuses and output
David Alban
extasia at extasia.org
Fri Mar 14 19:38:47 PDT 2008
greetings,
our sysadmins regularly need to restart a service on, say thirty
machines. the service takes two and a half minutes to restart. i'd
like to write a perl program they can use to parallelize the restart.
so that the whole operation takes three minutes rather than an hour or
more. i want to collect the statuses and any output of the service
restart commands.
i found the Bidirectional Communication with Yourself section of the
perlipc man page. i'm trying to hack their example so that only the
child writer writes to the parent reader. my hacked version forks two
child processes, which i want to run in parallel. each child process
ssh's to a host, sleeps a small amount of time, and then runs the
hostname command. but the child procs seem to be running serially.
#!/usr/bin/perl
use warnings;
use strict;
# log_timestamp() below comes from this module
use <LOCAL LOGGING MODULE>;
use IO::Handle;
my @hosts = qw( hostname_1 hostname_2 );
my $numprocs = @hosts;
my @output;
for my $instance ( 1..$numprocs ) {
my $index = $instance - 1;
pipe( CHILD_READER, PARENT_WRITER )
or die "can't pipe( CHILD_READER, PARENT_WRITER ): $!\n";
PARENT_WRITER->autoflush( 1 );
my $pid;
# parent
if ( $pid = fork() ) {
close PARENT_WRITER;
chomp( my $line = <CHILD_READER> );
$output[ $index ] = $line;
close CHILD_READER;
} # if
# child
else {
not defined $pid and die "can't fork: $!\n";
close CHILD_READER;
my $host = $hosts[ $index ];
my @results = qx{ ssh $host "sleep 5; hostname" };
print PARENT_WRITER
log_timestamp(),
" child pid $$; instance $instance; results => ",
join( '', @results );
close PARENT_WRITER;
exit;
} # if
} # for
for my $instance ( 1..$numprocs ) {
my $index = $instance - 1;
print $output[ $index ], "\n";
} # if
--------------------------------------------------------------------------------
i execute this as:
$ date; perl junk; date
and get:
Sat Mar 15 02:30:22 UTC 2008
2008-03-15 02:30:27 +0000 child pid 5469; instance 1; results => hostname_1
2008-03-15 02:30:32 +0000 child pid 5471; instance 2; results => hostname_2
Sat Mar 15 02:30:32 UTC 2008
it's running the second child process only after the first one
finishes, which defeats my goal of parallelizing. what am i missing?
there's so much stuff out there that promises to help with this and i
don't know whether i'm going down the wrong path. surely you fine
folks must have done stuff like this before. do indeed tell me to
rtfm, but please tell me which fm (or other doc) to r.
please also feel free to tell me i'm going about it totally the wrong
way, perhaps with a pointer in the general (better) direction.
thanks,
david
--
Live in a world of your own, but always welcome visitors.
More information about the SanFrancisco-pm
mailing list