Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re: AnyEvent timers by EV

by Krambambuli (Curate)
on Apr 03, 2015 at 18:40 UTC ( #1122376=note: print w/replies, xml ) Need Help??

in reply to AnyEvent timers by EV

Here's what's going on with the noticed odd-good/even-bad behavior:
#!/usr/bin/perl use common::sense; use AnyEvent::HTTP; use Data::Dumper; sub do { my $iter = shift; my $cv = AnyEvent->condvar; $cv->begin; http_get '', timeout => 2, # out-comment to get the even/odd behavior persistent => 0, sub { my ($body, $hdr) = @_; say "$iter $hdr->{Status}"; unless ($hdr->{Status} == 200) { warn Data::Dumper->Dump([$hdr],['hdr']); } $cv->end; } ; $cv->recv; } for (1..4) { &do($_); sleep(5); }
The documentation for that 'persistent' reads as follows:
        persistent => $boolean
               Try to create/reuse a persistent connection. When this flag is set (default: true for idempotent
               requests, false for all others), then "http_request" tries to re-use an existing (previously-created)
               persistent connection to the host and, failing that, tries to create a new one.

               Requests failing in certain ways will be automatically retried once, which is dangerous for non-
               idempotent requests, which is why it defaults to off for them. The reason for this is because the bozos
               who designed HTTP/1.1 made it impossible to distinguish between a fatal error and a normal connection
               timeout, so you never know whether there was a problem with your request or not.

               When reusing an existent connection, many parameters (such as TLS context) will be ignored. See the
               "session" parameter for a workaround.
This default persistence for idempotent requests conflicts with your 5 seconds sleeps - and that's why only every second connection attempt succeeds.


Replies are listed 'Best First'.
Re^2: AnyEvent timers by EV
by bash (Scribe) on Apr 04, 2015 at 13:31 UTC
    Ok, if this is "persistent" problem, how AnyEvent->now_update solves it?

    And why there is no time-out's at all like in my test-code #2?
      Most probably ->now_update clears the internal 'cache' entirely, so the persistence is swapped away.

      There is no *timer* timeout because in the example code the timeout is set to 300 seconds - a long time after every action is over. There are however *connection* timeouts - most probably the server closes connections that are idle for seconds, and you are keeping them idle by sleeping 5 seconds between the calls.

      That's what's happening, in sequence:

      1) successful GET; try to keep connection alive
      2) enter sleep
      3) server closes connection
      4) get awake and try a GET; failure. Clear connection cache
      5) sleep
      6) go to 1)

        300 sec timer is unnecessary
        Im intersting only on 2s timer for request
        My guess how it should work is:
        1) try to GET with timeout 2s (timer set to internal time + 2sec, but internal time has lag 5s)
        2) update internal time at ->recv.
        3) fire timeout for GET, because internal time now = real time, and timer+2s is now in the past
        4) throw error about timeout...
        But... maybe before check timeout for connection it already has success status for GET and timeout at this situation is dropped away

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1122376]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2022-11-27 19:08 GMT
Find Nodes?
    Voting Booth?