Skip to content

Instantly share code, notes, and snippets.

@renatocron
Created October 30, 2019 12:30
Show Gist options
  • Save renatocron/7bc23515940255c26d55bb5e8232c120 to your computer and use it in GitHub Desktop.
Save renatocron/7bc23515940255c26d55bb5e8232c120 to your computer and use it in GitHub Desktop.
use strict;
use Mojo::Promise;
use Mojo::UserAgent;
use DDP;
use Memory::Usage;
my $mu = Memory::Usage->new();
my $ua = Mojo::UserAgent->new->inactivity_timeout(1);
my $max_fail_num = 100;
my $total_success = 0;
my $total_err = 0;
#my $results_count = {};
my @retry_pos = (0, 0.5, 1, 2, 4, 5, 10, 20, 25, 30, 40);
$_ = $_ / 100 for @retry_pos; # Test only!
sub _exp_retry_fail {
my $x = shift;
my $t = $retry_pos[$x] || $retry_pos[-1];
return $t;
}
sub _success_cb {
my ($insistent_promises, $url, $fail_count) = @_;
$fail_count ||= 0;
return sub {
my ($tx) = @_;
if ($tx->res->code == 200) {
$insistent_promises->resolve($tx->res);
}
else {
$fail_count++;
$total_err++;
my $exp_retry = &_exp_retry_fail($fail_count);
if ($fail_count < $max_fail_num) {
Mojo::IOLoop->timer(
$exp_retry => sub {
$ua->get_p($tx->req->url->to_abs)
->then(
_success_cb($insistent_promises, $url, $fail_count))
->catch(
_fail_cb($insistent_promises, $url, $fail_count));
}
);
}
else {
$insistent_promises->reject("Too many errors on $url");
}
}
}
}
sub _fail_cb {
my ($insistent_promises, $url, $fail_count) = @_;
$fail_count ||= 0;
return sub {
my ($err) = @_;
#p ['_fail_cb', $err];
#$results_count->{x}{$url}{'timeout'}++;
my $exp_retry = &_exp_retry_fail($fail_count);
$fail_count++;
$total_err++;
if ($fail_count < $max_fail_num) {
Mojo::IOLoop->timer(
$exp_retry => sub {
$ua->get_p($url)
->then(
_success_cb($insistent_promises, $url, $fail_count))
->catch(_fail_cb($insistent_promises, $url, $fail_count));
}
);
}
else {
$insistent_promises->reject('Too many conections fails', $url);
}
};
}
my %current_p;
my $errored;
my $pid = 0;
$mu->record('starting work');
for my $num (1 .. 20) {
my $insistent_promises = Mojo::Promise->new;
my $mine_pid = $pid++;
$current_p{$mine_pid} = $insistent_promises;
my $url = 'http://localhost:3000/maybe_fail?num=' . $num;
$ua->get_p($url)->then(&_success_cb($insistent_promises, $url, 0))
->catch(_fail_cb($insistent_promises, $url, 0));
$insistent_promises->then(
sub {
my ($res) = @_;
$total_success++;
}
)->catch(
sub {
print STDERR "cancel everythiiiiiiiiiiing!!!\n\n\n";
$errored++;
#Mojo::Promise->reset;
}
)->finally(
sub {
delete $current_p{$mine_pid};
}
);
Mojo::Promise->all($insistent_promises);
$mu->record('Iteration ' . $num) if $num % 1000 == 0;
if (scalar keys %current_p > 50) {
Mojo::Promise->race(values %current_p)->wait;
}
}
my @values = values %current_p;
use DDP;
p \@values;
Mojo::Promise->all(@values)->wait if @values;
$mu->record('Last Iteration');
$mu->dump();
if ($errored) {
die "Please do not commit!!!\n";
}
p [$total_success, $total_err];
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment