Skip to content

Commit

Permalink
brought back request_timeout attribute by popular demand
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Jan 21, 2012
1 parent 508cb2a commit 0ee2405
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
1 change: 1 addition & 0 deletions Changes
@@ -1,6 +1,7 @@
This file documents the revision history for Perl extension Mojolicious.

2.46 2012-01-21 00:00:00
- Added EXPERIMENTAL request_timeout attribute to Mojo::UserAgent.
- Improved documentation.
- Improved tests.
- Fixed small parser bug in Mojo::Message::Response.
Expand Down
38 changes: 30 additions & 8 deletions lib/Mojo/UserAgent.pm
Expand Up @@ -23,6 +23,7 @@ has key => sub { $ENV{MOJO_KEY_FILE} };
has max_connections => 5;
has max_redirects => sub { $ENV{MOJO_MAX_REDIRECTS} || 0 };
has name => 'Mojolicious (Perl)';
has request_timeout => 0;
has transactor => sub { Mojo::UserAgent::Transactor->new };
has websocket_timeout => 300;

Expand Down Expand Up @@ -291,17 +292,21 @@ sub _connected {
my $loop = $self->_loop;
$loop->stream($id)->timeout($self->inactivity_timeout);

# Request timeout
my $c = $self->{connections}->{$id};
my $timeout = $self->request_timeout;
weaken $self;
$c->{timeout} =
$loop->timer($timeout => sub { $self->_error($id, 'Request timeout.') })
if $timeout;

# Store connection information in transaction
my $tx = $self->{connections}->{$id}->{tx};
$tx->connection($id);
(my $tx = $c->{tx})->connection($id);
my $handle = $loop->stream($id)->handle;
$tx->local_address($handle->sockhost);
$tx->local_port($handle->sockport);
$tx->remote_address($handle->peerhost);
$tx->remote_port($handle->peerport);
$tx->local_address($handle->sockhost)->local_port($handle->sockport);
$tx->remote_address($handle->peerhost)->remote_port($handle->peerport);

# Start writing
weaken $self;
$tx->on(resume => sub { $self->_write($id) });
$self->_write($id);
}
Expand Down Expand Up @@ -361,8 +366,11 @@ sub _finish {
sub _handle {
my ($self, $id, $close) = @_;

# Request timeout
my $c = $self->{connections}->{$id};
$self->_loop->drop($c->{timeout}) if $c->{timeout};

# Finish WebSocket
my $c = $self->{connections}->{$id};
my $old = $c->{tx};
if ($old && $old->is_websocket) {
$self->{processing} -= 1;
Expand Down Expand Up @@ -761,6 +769,20 @@ Value for C<User-Agent> request header, defaults to C<Mojolicious (Perl)>.
Domains that don't require a proxy server to be used.
=head2 C<request_timeout>
my $timeout = $ua->request_timeout;
$ua = $ua->request_timeout(5);
Maximum amount of time in seconds sending the request and receiving the whole
response may take before getting canceled, defaults to C<0>. Setting the
value to C<0> will allow the user agent to wait indefinitely. The timeout
will reset for every followed redirect. Note that this attribute is
EXPERIMENTAL and might change without warning!
# Total limit of 8 seconds
$ua->max_redirects(0)->connect_timeout(3)->request_timeout(5);
=head2 C<transactor>
my $t = $ua->transactor;
Expand Down
17 changes: 16 additions & 1 deletion t/mojolicious/longpolling_lite_app.t
Expand Up @@ -6,7 +6,7 @@ BEGIN {
$ENV{MOJO_IOWATCHER} = 'Mojo::IOWatcher';
}

use Test::More tests => 125;
use Test::More tests => 128;

# "I was God once.
# Yes, I saw. You were doing well until everyone died."
Expand Down Expand Up @@ -416,6 +416,21 @@ $t->get_ok('/finish')->status_is(200)
->header_is('X-Powered-By' => 'Mojolicious (Perl)')->content_is('Finish!');
ok !$finish, 'finish event timing is right';

# GET /too_long (request timeout)
$tx = $t->ua->request_timeout('0.5')->build_tx(GET => '/too_long');
$buffer = '';
$tx->res->body(
sub {
my ($self, $chunk) = @_;
$buffer .= $chunk;
}
);
$t->ua->start($tx);
is $tx->res->code, 200, 'right status';
is $tx->error, 'Request timeout.', 'right error';
is $buffer, 'how', 'right content';
$t->ua->request_timeout(0);

# GET /too_long (inactivity timeout)
$tx = $t->ua->inactivity_timeout('0.5')->build_tx(GET => '/too_long');
$buffer = '';
Expand Down

0 comments on commit 0ee2405

Please sign in to comment.