shanu_040 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,
I am using this code to get the desired result and It works well. But It waits for all the child process to exit and then only it display the result.
What I want is as soon as on process retrieves the result it should display. It should not wait for all the process to get finished.
Variable Definition:
$serialized_searches: is a reference to a hash. key->integer value->object to class.
$search_string: Any string value
$res_man->site_modules: any module
$results = SOAP::Lite -> uri($PARASEARCH_CLIENT_URI) -> proxy($PARASEARCH_CLIENT_PROXY, timeout => $PARASEARCH_PARA +LLEL_TIMEOUT + 15) -> parallel_search($serialized_searches, $search_string, $max_ +hits, $res_man->site_modules) -> result; };
sub parallel_search { my ($self, $serialized_searches, $rawsearch, $max_hits, $site_modu +les) = @_; my (%return, $result_set); 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_start(sub { my ($pid,$ident)=@_; }); $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) = @_; # 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($pa +rsed_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; } $pm->wait_all_children; eval { foreach my $key (keys %$searches) { my $filename = $PARASEARCH_SHARED_MEM . $$ . escape($key); 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{$key} = $result_set; } }; if ($@) { print STDERR "Problem with search module: $@\n"; } my $temp = $obj->serialize(\%return); return($temp); }

Replies are listed 'Best First'.
Re: Running a Perl Code in different Processes
by Anonymous Monk on Oct 15, 2008 at 08:42 UTC
    Display? Do you mean print? You would rewrite
    $pm->run_on_finish(sub { my ($pid, $exit_code, $ident) = @_; # print STDERR "database $ident done = exit $exit_code \n"; print "something something $ident ...\n"; });
    Hmm, it looks like that is a chunk of DBWIZ::Search::Parasearch (Bundle::DBWIZ), a SOAP server for some kind of CGI/SOAP/AJAX search program.

    I don't see how you can accomplish what you want without rewriting the client as well as the server, which is why you're probably better off contacting DBWIZ developers for help.

      Yes..You are right..I have also tried parallel::SubFork::Task and it works. But have you tried DBWIZ??? See the problem with DBWIZ is that it waits for all the forked process get finished and then only create the result sets.
      What I want each search module returns results as soon as it is completed, Instead of waiting for searches to complete.
Re: Running a Perl Code in different Processes
by cdarke (Prior) on Oct 15, 2008 at 10:02 UTC
    I don't know anything about DBWIZ. Assuming it displays its results to STDOUT you may be being caught by buffering. It might be as simple as adding $|=1;, but the app might not be using STDOUT, or might reset the buffering. Worth a try though.