Skip to content

Instantly share code, notes, and snippets.

@renatocron
Created October 29, 2019 23:08
Show Gist options
  • Save renatocron/ea89f2058ebfa87d802d5099563af572 to your computer and use it in GitHub Desktop.
Save renatocron/ea89f2058ebfa87d802d5099563af572 to your computer and use it in GitHub Desktop.
use strict;
use Mojo::Promise;
use Mojo::UserAgent;
use DDP;
my $ua = Mojo::UserAgent->new->with_roles('+Queued')->inactivity_timeout(60);
my $max_fail_num = 100;
my $results_count = {};
sub _success_cb {
my ($insistent_promises, $url, $fail_count) = @_;
$fail_count ||= 0;
return sub {
my ($tx) = @_;
$results_count->{x}{$tx->res->json->{num}}{$tx->res->code}++;
use DDP;
p $fail_count;
if ($tx->res->code == 200) {
$insistent_promises->resolve($tx->res);
}
else {
$fail_count++;
if ($fail_count < $max_fail_num) {
$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];
$fail_count++;
if ($fail_count < $max_fail_num) {
$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);
}
};
}
# how to remove this, or at least, should I remove the item when the promises finish?
my @all_ps;
my $errored;
for my $num (1 .. 20) {
my $insistent_promises = Mojo::Promise->new;
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) = @_;
$results_count->{p}{$res->json->{num}}{$res->code}++;
}
)->catch(
sub {
print STDERR "cancel everythiiiiiiiiiiing!!!\n\n\n";
$errored++;
Mojo::Promise->reset;
}
);
push @all_ps, $insistent_promises;
Mojo::Promise->all($insistent_promises);
}
Mojo::Promise->all(@all_ps)->wait;
if ($errored) {
die "Please do not commit!!!\n";
}
p $results_count;
exit;
# I tried this but did not worked:
my $is_done = 0
; # TODO check if queue is empty, because it may never return run the event if not!
$ua->on(
queue_empty => sub {
use DDP;
p "on is queue_empty!";
$is_done = 1;
}
);
while (1) {
Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
Mojo::IOLoop->next_tick(
sub {
if (!$is_done) {
Mojo::IOLoop->stop;
}
}
);
}
# this never run
p $results_count;
use Mojolicious::Lite;
use utf8;
get '/maybe_fail' => sub {
my $c = shift;
my $status = rand > 0.9 ? 200 : 400;
# select undef, undef, undef, rand() / 4;
$c->render(json => {num => $c->req->param('num'),}, status => $status,);
};
# Start the Mojolicious command system
app->start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment