Skip to content

Instantly share code, notes, and snippets.

@wchristian
Created November 3, 2010 14:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wchristian/661177 to your computer and use it in GitHub Desktop.
Save wchristian/661177 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use 5.10.1;
use strict;
use warnings;
use HTTP::Request::Common 'POST';
use AnyEvent::HTTP;
use Benchmark;
my $t0 = Benchmark->new;
my @ids = ( 34..300 );
my @requests = map POST( "http://eve-metrics.com/api/item.json", [ type_ids => $_ ] ), @ids;
my @responses = parallel_download( 10, @requests );
# wait till all finished
print "Finished\n";
#
#for ( @responses ) {
# print $_->[1]{Status};
#}
my $t1 = Benchmark->new;
my $td = timediff($t1, $t0);
print "the code took: ",timestr($td),"\n";
sub parallel_download {
my ( $workers, @requests ) = @_;
my $real_worker_max = sanitize_worker_max( $workers, scalar @requests );
my @responses;
my $cv = AnyEvent->condvar;
for ( 1 .. $real_worker_max ) {
$cv->begin;
say "$_ started";
my $req = pop @requests;
add_request( \@requests, $req, $cv, \@responses, $_ );
}
$cv->recv;
return @responses;
}
sub add_request {
my ( $requests, $req, $cv, $responses, $runner_id ) = @_;
say "$runner_id accepted new request";
http_request(
$req->method => $req->uri->as_string,
body => $req->content,
sub {
push @{$responses}, [ @_ ];
return $cv->end( say "$runner_id ended" ) if !@{$requests};
my $next_req = pop @{$requests};
add_request( $requests, $next_req, $cv, $responses, $runner_id );
}
);
return;
}
sub sanitize_worker_max {
my ( $asked_max, $queue_size ) = @_;
die "max should be 0 or more" if $asked_max < 0;
return $queue_size if !$asked_max; # 0 = as many parallel as possible
return $queue_size if $asked_max > $queue_size; # not more than the request count
return $asked_max;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment