CPAN::Forum
Parallel-ForkManager - Call in a subroutine on callback: run_on_finish
| Posted on Tue Dec 2 10:48:35 2008 by shanuamitshanu |
| Call in a subroutine on callback: run_on_finish |
|
HI,
There is a sub routine below return a hash reference to the calling sub routine.
I am using this sub routine in a search program which searches different databases. Currently it waits for all the process to be finished(it should). But I want to make it like, as soon as it one process has finished it should return the hash and keep searching on other databases on other child process. How can I do that? can any body suggest me other way of doing the same?, or any other idea?
Any help would be highly appreciable
sub parallel_search {
my ($self, $serialized_searches, $rawsearch, $max_hits, $site_modules) = @_;
my (%return);
my $obj = Data::Serializer->new(
serializer => 'Storable',
portable => '1',
encoding => 'b64',
);
my $searches = $obj->deserialize($serialized_searches);
my $t0 = [gettimeofday];
my $pm = new Parallel::ForkManager($PARASEARCH_MAX_PROCESSES);
$pm->run_on_wait(sub {
my ($pid, $ident) = @_;
my $elapsed = tv_interval ( $t0, [gettimeofday]);
my $remaining = scalar(keys %{$pm->{processes}});
#print "$$ waiting ... $elapsed\n";
#print STDERR " -- remaining $remaining\n";
#print STDERR "processes " . $pm->{processes} . "\n";
if ($elapsed > $PARASEARCH_PARALLEL_TIMEOUT) {
# print STDERR "timeout exceeded $remaining processes remain\n";
foreach my $process (keys %{$pm->{processes}}) {
# print STDERR " .. $process\n";
kill 'TERM' => $process;
}
}
},
0.5
);
$pm->run_on_finish(sub {
my ($pid, $exit_code, $ident) = @_;
eval {
my $filename = $PARASEARCH_SHARED_MEM . $$ . escape($ident);
my $result_set;
if (-e $filename) {
$result_set = $obj->retrieve($filename);
unlink($filename);
}
else {
# need a new $timeout_result object every loop
my $timeout_result = new DBWIZ::Search::ResultSet;
$timeout_result->status('timeout');
$timeout_result->hits(-5);
$result_set = $timeout_result;
}
$return{$ident} = $result_set;
};
if ($@) { print STDERR "Problem with search module: $@\n"; }
# print STDERR "database $ident done = exit $exit_code \n";
});
foreach my $key (keys %$searches) {
my $pid = $pm->start($key) and next;
if (-e $site_modules) {
my @orig_inc = @INC;
unshift (@INC, $site_modules);
eval 'require ' . ref($$searches{$key}) . ';';
@INC = @orig_inc;
}
else {
eval 'require ' . ref($$searches{$key}) . ';';
}
if ($@) {
print "error $@\n";
}
my ($parsed_search, $result_set);
eval {
$parsed_search = $$searches{$key}->parse_search();
};
if ($@) {
print STDERR "error parsing search: $@";
$result_set = new DBWIZ::Search::ResultSet;
$result_set->status($@);
$result_set->hits(-6);
}else{
eval {
$$searches{$key}->max_hits($max_hits);
$result_set = $$searches{$key}->get_search_results($parsed_search, $key);
};
if ($@) {
print STDERR "bad eval resource [$key]: $@ \n";
$result_set = new DBWIZ::Search::ResultSet;
$result_set->status($@);
$result_set->hits(-3);
}
}
$result_set->rawsearch($rawsearch);
eval {
$obj->store($result_set, $PARASEARCH_SHARED_MEM . getppid . escape($key));
};
if ($@) {
print STDERR "from eval: $@ \n";
$result_set = new DBWIZ::Search::ResultSet;
$result_set->status($@);
$result_set->hits(-11);
}
$pm->finish($key);
}
$pm->wait_all_children;
my $temp = $obj->serialize(\%return);
return($temp);
}
|
| Write a response |
(5)
]