Skip to content

Commit 5398671

Browse files
committed
Add support for multiple download attempts for assets that need to be fetched
This will be disabled by default, and can be enabled with `$app->asset->store->retries(5)`.
1 parent f44e08f commit 5398671

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

lib/Mojolicious/Plugin/AssetPack/Store.pm

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use Mojo::URL;
88
use Mojolicious::Types;
99
use Mojolicious::Plugin::AssetPack::Asset;
1010
use Mojolicious::Plugin::AssetPack::Util qw(diag checksum has_ro DEBUG);
11+
use Time::HiRes qw(sleep);
1112

1213
use constant CACHE_DIR => 'cache';
1314

@@ -26,6 +27,8 @@ has asset_class => 'Mojolicious::Plugin::AssetPack::Asset';
2627
has default_headers => sub { +{"Cache-Control" => "max-age=31536000"} };
2728
has fallback_headers => sub { +{"Cache-Control" => "max-age=60"} };
2829
has fallback_templates => sub { +{%FALLBACK_TEMPLATES} };
30+
has retry_delay => 3;
31+
has retries => 0;
2932

3033
has _types => sub {
3134
my $t = Mojolicious::Types->new;
@@ -257,14 +260,22 @@ sub _download {
257260

258261
return $asset if $attrs{url}->host ne 'local' and $asset = $self->_already_downloaded($url);
259262

260-
my $tx = $self->ua->get($url);
261-
my $h = $tx->res->headers;
263+
my $tx;
264+
my $retries = $self->retries;
265+
while (1) {
266+
$tx = $self->ua->get($url);
267+
last unless my $err = $tx->error;
268+
269+
if ($retries-- > 0) {
270+
sleep $self->retry_delay;
271+
next;
272+
}
262273

263-
if (my $err = $tx->error) {
264274
$self->_log->warn("[AssetPack] Unable to download $url: $err->{message}");
265275
return undef;
266276
}
267277

278+
my $h = $tx->res->headers;
268279
my $ct = $h->content_type || '';
269280
if ($ct ne 'text/plain') {
270281
$ct =~ s!;.*$!!;
@@ -388,6 +399,20 @@ This is currently an EXPERIMENTAL feature.
388399
389400
See L<Mojolicious::Static/paths> for details.
390401
402+
=head2 retry_delay
403+
404+
my $delay = $self->retry_delay;
405+
$self = $self->retry_delay(0.5);
406+
407+
Delay in seconds between download attempts for assets that need to be fetched, defaults to C<3>.
408+
409+
=head2 retries
410+
411+
my $retries = $self->retries;
412+
$self = $self->retries(5);
413+
414+
Number of times asset downloads will be attempted for assets that need to be fetched, defaults to C<0>.
415+
391416
=head2 ua
392417
393418
$ua = $self->ua;

t/fetch-retry.t

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use lib '.';
2+
use t::Helper;
3+
4+
use Mojo::IOLoop;
5+
use Mojo::Server::Daemon;
6+
use Mojolicious;
7+
8+
my $t = t::Helper->t(pipes => [qw(Css Fetch)]);
9+
10+
my $app = Mojolicious->new;
11+
$app->config->{attempts} = 0;
12+
$app->routes->get(
13+
'/test.css' => sub {
14+
my $c = shift;
15+
return $c->render(data => 'Internal server error', status => 500) if $c->app->config->{attempts}++ <= 2;
16+
$c->render(data => 'body { color: #00f }');
17+
}
18+
);
19+
my $responses = [];
20+
$app->hook(
21+
before_dispatch => sub {
22+
shift->on(finish => sub { push @$responses, shift->res->code });
23+
}
24+
);
25+
my $daemon = Mojo::Server::Daemon->new(listen => ['http://*'], ioloop => $t->app->asset->ua->ioloop, app => $app);
26+
my $port = $daemon->start->ports->[0];
27+
28+
subtest 'Defaults' => sub {
29+
is $t->app->asset->store->retries, 0, 'no retries by default';
30+
is $t->app->asset->store->retry_delay, 3, '3 second retry delay by default';
31+
};
32+
33+
subtest 'Download asset with multiple attempts' => sub {
34+
$t->app->asset->store->retries(3)->retry_delay(0.1);
35+
$t->app->asset->process('app.css' => "http://127.0.0.1:$port/test.css");
36+
37+
$t->get_ok('/')->status_is(200)->content_like(qr{Hello world});
38+
$t->get_ok($t->tx->res->dom->at('link')->{href})->status_is(200)->content_like(qr{body.+color.+00f});
39+
is_deeply $responses, [500, 500, 500, 200], 'right responses';
40+
};
41+
42+
done_testing;
43+
44+
__DATA__
45+
@@ index.html.ep
46+
%= asset 'app.css'
47+
Hello world

0 commit comments

Comments
 (0)