#!/usr/bin/perl $|=1; print "Start time ".(localtime). "\n"; use strict; use threads; use CGI qw(:standard); use XML::Simple; use JSON qw(encode_json); use MIME::Base64 qw(encode_base64); use DBI; use SOAP::Lite; use POSIX qw(ceil); use Data::Dumper; use CHI; $XML::Simple::PREFERRED_PARSER='XML::Parser'; $SOAP::Constants::DO_NOT_USE_CHARSET = 1; my (@req,@odata,@errdet)=(); my %threads=(); foreach my $vnd (@req){ #$threads{$vnd}=threads->create({ 'context' => 'list', 'exit' => 'thread_only' },\&startthread,$vnd,$SCH); $threads{$vnd}=async{&startthread($vnd,$SCH) }; } cede; foreach my $vnd (keys %threads) { my($err,$data) =$threads{$vnd}->join(); if ($err eq 'N') { push @odata,@{$data}; } }elseif($err eq 'Y'){ push @errdet,$data; }elsif($threads{$vnd}->error) # with threads it was useful, { push @errdet,{ Vnd=>$vnd, ErrorCode=>26,ErrorMsg=>$threads{$vnd}->error}; } } sub startthread { my ($vendor,$SCH)=@_; my($err,$data) =(); require './'.$vendor.'functions.pl"; #load vendor specific code ($err,$data)=&getvendordata($SCH); return($err,$data); } #vendor functions has somewhat code like this besides functions specific to each vendor api #fetch data serially in a loop waiting for each call to finish before going on next sub getvendordata { my $SCH=shift; #perform vendor specific tasks mostly SOAP::Lite calls to api #Has to perform multiple calls some of them depend on output of previous calls #Also have to make simultaneous calls which may not be related to each other can be done parallelly. #e.g. first call to api returns a list of products subsequent calls to fetch details. #If i start threads/forks again here most of the time program crashes :( my ($err,@data)=(); my @products=getproduects(); #Maybe i can start coro routines here to get all listed details simultaneously foreach my $product (@products) { #fetch product details over api push @data,$product->getdetails; } return ($err,\@data); } #### use strict; use Coro; #use Coro::LWP; use LWP::Protocol::AnyEvent::http; use CGI qw(:standard); use XML::Simple; use JSON qw(encode_json); use MIME::Base64 qw(encode_base64); use DBI; use POSIX qw(ceil); use Data::Dumper; use CHI; use SOAP::Lite; use SOAP::Transport::HTTP; $XML::Simple::PREFERRED_PARSER='XML::Parser'; $SOAP::Constants::DO_NOT_USE_CHARSET = 1; my (@req,@odata,@errdet)=(); my %threads=(); foreach my $vnd (@req){ #$threads{$vnd}=threads->create({ 'context' => 'list', 'exit' => 'thread_only' },\&startthread,$vnd,$SCH); $threads{$vnd}=async{&startthread($vnd,$SCH) }; } cede; foreach my $vnd (keys %threads) { my($err,$data) =$threads{$vnd}->join(); if ($err eq 'N') { push @odata,@{$data}; } }elseif($err eq 'Y'){ push @errdet,$data; }elsif($threads{$vnd}->error) # with threads it was useful, { push @errdet,{ Vnd=>$vnd, ErrorCode=>26,ErrorMsg=>$threads{$vnd}->error}; } } sub startthread { my ($vendor,$SCH)=@_; my($err,$data) =(); require './'.$vendor.'functions.pl"; #load vendor specific code ($err,$data)=&getvendordata($SCH); return($err,$data); } #vendor functions has somewhat code like this besides functions specific to each vendor api #fetch data asyncronously with coro async for each product sub getvendordata { my $SCH=shift; #perform vendor specific tasks mostly SOAP::Lite calls to api #Has to perform multiple calls some of them depend on output of previous calls #Also have to make simultaneous calls which may not be related to each other can be done parallelly. #e.g. first call to api returns a list of products subsequent calls to fetch details. #If i start threads/forks again here most of the time program crashes :( my ($err,@data)=(); my @products=getproduects(); #Maybe i can start coro routines here to get all listed details simultaneously my @tasks=(); foreach my $product (@products) { #fetch product details over api push @tasks,async {push @data,$product->getdetails}; } foreach my $task (@ftasks) { $task->join(); } return ($err,\@data); }