Skip to content

Instantly share code, notes, and snippets.

@brianmed
Created February 15, 2014 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianmed/9021900 to your computer and use it in GitHub Desktop.
Save brianmed/9021900 to your computer and use it in GitHub Desktop.
Non-blocking Mojo::Useragent benchmarker
use strict;
use warnings;
use v5.10;
use Mojo::UserAgent;
use Mojo::IOLoop;
use Benchmark;
use Getopt::Long;
my @slots;
my %Options;
GetOptions (\%Options, "get=s", "run_time=i", "slots=i");
my $get = $Options{get};
my $run_time = $Options{run_time};
my $slots = $Options{slots};
die("Please pass in a URL [-get]") unless $get;
die("Please pass in a running time [-run_time]") unless $run_time;
die("Please pass in number of slots [-slots]") unless $slots;
my $state = "running";
my $running;
my $requests = {};
my $slotidx = $slots - 1;
my $start_time = Benchmark->new;
Mojo::IOLoop->timer($run_time => sub { $state = "stop" });
my $ua = Mojo::UserAgent->new;
$ua->on(stop => sub {
--$running;
unless ($running) {
my $count;
$count += $$requests{$_}{count} for (0 .. $slotidx);
my $stop_time = Benchmark->new;
my $td = timediff($stop_time, $start_time);
say("$count requests took:", timestr($td));
say("HTTP Response codes:");
foreach my $code (sort({ $a <=> $b} keys %{$$requests{code}})) {
say("$code: $$requests{code}{$code}");
}
exit;
}
});
sub tx {
my $tx = $ua->build_tx(GET => $get);
$tx->on(finish => sub {
my ($tx) = @_;
my $code = $tx->res->code;
++$$requests{code}{$code};
});
$tx;
}
foreach my $idx (0 .. $slotidx) {
$$requests{$idx}{count} = 0;
$slots[$idx] = Mojo::IOLoop->delay;
$slots[$idx]->on(finish => sub {
++$$requests{$idx}{count};
if ("stop" eq $state) {
$ua->emit_safe("stop");
}
else {
my $tx = tx;
my $end = $slots[$idx]->begin;
$ua->start($tx => sub {
my ($ua, $tx) = @_;
$end->();
});
}
});
my $tx = tx;
my $end = $slots[$idx]->begin;
$ua->start($tx => sub {
my ($ua, $tx) = @_;
$end->();
});
++$running;
}
my $stats = sub {
my $count;
state $last = 0;
$count += $$requests{$_}{count} for (0 .. $slotidx);
my $whence = Benchmark->new;
my $td = timediff($whence, $start_time);
printf("$count [%d] requests have taken: %s\n", $count - $last, timestr($td));
$last = $count;
};
Mojo::IOLoop->recurring(1 => $stats);
Mojo::IOLoop->start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment