#!/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 specif
+ic 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 pr
+evious 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 call
+s to fetch details.
#If i start threads/forks again here most of the time program cras
+hes :(
my ($err,@data)=();
my @products=getproduects();
#Maybe i can start coro routines here to get all listed detail
+s simultaneously
foreach my $product (@products)
{
#fetch product details over api
push @data,$product->getdetails;
}
return ($err,\@data);
}
Coro Code
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 specif
+ic 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 pr
+evious 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 call
+s to fetch details.
#If i start threads/forks again here most of the time program cras
+hes :(
my ($err,@data)=();
my @products=getproduects();
#Maybe i can start coro routines here to get all listed detail
+s 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);
}
I wait for all threads to finish by joining them. |