ikegami / perl-LWP-Protocol-AnyEvent-http

Event loop friendly HTTP and HTTPS backend for Perl's LWP
http://search.cpan.org/dist/LWP-Protocol-AnyEvent-http/
Creative Commons Zero v1.0 Universal
9 stars 6 forks source link

How to set overall timeout of request without access to the guard object? #8

Closed ghost closed 7 years ago

ghost commented 9 years ago

How can one set the overall timeout of the request? According to the AnyEvent::HTTP documentation each connect attempt will reset the timeout, as will read or write activity. If I had access to the guard object, I could create a timer to delete the guard. How can I create an overall timer when using LWP-Protocol-AnyEvent-http?

ikegami commented 9 years ago

Could you please provide a snippet using LWP::UserAgent that does what you want unless "use LWP::Protocol::AnyEvent::http;" is added.

ghost commented 9 years ago

For plain LWP without AnyEvent, this is similar to what I want to accomplish:

my $res;
eval {
    local $SIG{ALRM} = sub { die "alarm timed out\n" };
    alarm $ua->timeout;
    $res = $ua->get($url);
    alarm 0;
};
if (not $res and $@) {
    require HTTP::Response;
    return HTTP::Response->new(408, $@);
}

For plain AnyEvent, I can do something like:

my $timer;
my $guard = http_request GET => $url, ..., sub { $timer = undef; callback(...) };
$timer  = AE::timer $timeout, 0, sub { $guard = undef };

When using LWP::Protocol::AnyEvent::http with Coro, I call the request like this:

undef $timeout;
$guard = async {
    $ua->get($url);
     ....
};
$timeout = AE::timer $ua->timeout, 0, sub {
    undef $guard
     # or $guard->cancel/safe_cancel
 };

But when encountering a bad server, the timeout only works about 50% of the time and hangs the other 50% of the time.

ikegami commented 9 years ago

On Wed, Dec 24, 2014 at 5:01 AM, BGMNT notifications@github.com wrote:

For plain LWP without AnyEvent, this is similar to what I want to accomplish:

my $res; eval { local $SIG{ALRM} = sub { die "alarm timed out\n" }; alarm $ua->timeout; $res = $ua->get($url); alarm 0; }; if (not $res and $@) { require HTTP::Response; return HTTP::Response->new(408, $@); }

Signals can't be supported. Assuming it's possible at all, it would be far too big a mess.

When using LWP::Protocol::AnyEvent::http with Coro, I call the request like

this:

undef $timeout; $guard = async { $ua->get($url); .... }; $timeout = AE::timer $ua->timeout, 0, sub { undef $guard

or $guard->cancel/safe_cancel

};

But when encountering a bad server, the timeout only works about 50% of the time and hangs the other 50% of the time.

async doesn't return a guard -- in fact, the returned value is often ignored -- so that means "undef $guard;" doesn't do anything.

So your complaining that either 1) the timer created by AE::timer doesn't get called when LWP is working, or 2) $coro->cancel and $coro->safe_cancel don't cause LWP to abort. I can look into it, but it would really help for me to have a program that exhibits the problem. Could you please provide a minimal, runnable program that exhibits the problem?

Thanks, Eric

ikegami commented 9 years ago

On Wed, Dec 24, 2014 at 11:14 AM, Eric Brine ikegami@adaelis.com wrote:

When using LWP::Protocol::AnyEvent::http with Coro, I call the request like this:

undef $timeout; $guard = async { $ua->get($url); .... }; $timeout = AE::timer $ua->timeout, 0, sub { undef $guard

or $guard->cancel/safe_cancel

};

But when encountering a bad server, the timeout only works about 50% of the time and hangs the other 50% of the time.

async doesn't return a guard -- in fact, the returned value is often ignored -- so that means "undef $guard;" doesn't do anything.

So your complaining that either 1) the timer created by AE::timer doesn't get called when LWP is working, or 2) $coro->cancel and $coro->safe_cancel don't cause LWP to abort. I can look into it, but it would really help for me to have a program that exhibits the problem. Could you please provide a minimal, runnable program that exhibits the problem?

So I tried to replicate the problem on my own, yet even with $thread->safe_cancel, it seens to always work for me. See attached programs. a.pl shows it works with AnyEvent::HTTP. b.pl shows it works with LWP + LWP::Protocol::AnyEvent::http.

If you want this to process, I'll need the requested information from you.

ikegami commented 9 years ago

Meh, the attachments didn't show up in git. You can find them here:

a.pl: https://gist.github.com/anonymous/7719e0f6c9545b94b932 b.pl: https://gist.github.com/anonymous/5cd6620534b4f5ca6865