Async .10

Async .10

am 25.09.2006 18:33:13 von Todd English

Group,

I work for a company as security developer and have recently been asked
to streamline our build process. The build process is driven by a
single machine which connects to all the build hosts and builds our
products.

The driver was written in Perl and does all of this sequentially. I
found the Async Perl package from Google (perl+async) and tried to use
it to optimize our process so that building would only take as long as
the slowest platform.

Here is where things get interesting. I implemented everything, and
started seeing that the proc result was blank for allot of our build
results. I'm very new to Perl (as in this is my 4th day using it) so I
broke out a simple program to reproduce the results. Originally, for
the long computation, I was sleeping (as per the example) and the
example worked just fine. I figured it must be my problem and spent a
couple more days learning Perl. I just happened to run the test program
once more today and noticed that one platform didn't respond. So,
instead of sleeping I did something a little more random (as far as
when the function will return) and boom, it happens all the time now.

I would be very willing to help explore this problem, test patches or
even the async fix code (which I tried, unsuccessfully), but I will
need a little direction to do this. Perhaps I am using the package
incorrectly and someone could point out my mistake?

Any help would be appreciated. Thank you for taking the time to read
this,

Todd English

-----------Sample Code------------

#!/usr/bin/perl -w

use Async;

sub long_running_computation {
# This function simulates a computation that takes a long time to
run
my ($name, $host) = @_;
system qq{find ./ -type f 2>&1 >/dev/null};
# if we sleep instead of do something more unpredictable, then works
most of the time
# sleep 10;
return "$name $host has Failed";
}

my %host =
(
'rhel3-ia32' => 'gray',
'rhel4-ia32' => 'x.x.x.x',
'sles9-ia32' => 'y.y.y.y',
'sles10-ia32' => 'maroon',
'rhel3-x64' => 'white',
'rhel4-x64' => 'ivory',
'sles9-x64' => 'skyblue',
'sles10-x64' => 'orange',
'rhel3-ia64' => 'chartreuse',
'rhel4-ia64' => 'cyan',
'sles9-ia64' => 'goldenrod',
'rhel4-s390' => 'rh4as',
'sles9-s390' => 'mambo',
'sol10-x64' => 'brown',
'sol10-sparc' => 'green',
'sol8-sparc' => 'blue',
'sol7-sparc' => 'red',
'sol9-sparc' => 'black',
'hpux-parisc' => 'purple',
'hpux11-ia64' => 'yellow'
);

my %proc_result;
my %build_result;

while (my ($name, $host) = each %host)
{
$proc_result{$name} = Async->new(sub{ long_running_computation
($name, $host) } );
}

# This doesn't work
#while ( (my $name, $proc) = each %proc_result)
#{
# $build_result{$name} = $proc->result('1');
#}

#neither does this
while( 0 < scalar(keys %proc_result) )
{
my @host_list_to_delete;
while( ($name) = each %proc_result)
{
print "checking if $name is ready\n";
if($proc_result{$name}->ready)
{
my $error;
if($error = $proc_result{$name}->error)
{
#$build_result{$name} = $error;
$build_result{$name} = "Async indicates a failure error
occured: $error !";
}
else
{
$build_result{$name} = $proc_result{$name}->result;
}
push(@host_list_to_delete, $name);

undef $proc_result{$name}; #not sure why this is here, but
is was in the sample docs
}
}

foreach my $item (@host_list_to_delete)
{
delete ( $proc_result{$item} );
}

sleep 10;
}

print "done with long running computation\n";
while (my($host_name, $result) = each %build_result)
{
printf "%s\t%s\n", $host{$host_name}, $result;
}