nuclon has asked for the wisdom of the Perl Monks concerning the following question:

I've got in trouble with POE. I'm working on crawling software and use POE::Component::Client::HTTP.

It works well from start and during a hour or so, but then I see big list of "FIN_WAIT_2" connections in netstat output and any attempt to make a request gives

500 Internal Server Error
Cannot connect to somehost.com:80 (connect error 60: Operation timed out)

I think that PoCo::Keepalive thinks these connections are alive and tries to send request with them but gets this message immediately.

What can I do with it?

  • Comment on POE::Component::Client::HTTP, Keepalive, FIN_WAIT_2

Replies are listed 'Best First'.
Re: POE::Component::Client::HTTP, Keepalive, FIN_WAIT_2
by rcaputo (Chaplain) on Nov 24, 2008 at 16:53 UTC

    FIN_WAIT_2 happens when the local end of a socket is closed and the operating system is waiting for a signal that the remote end has closed their side. In your case, enough connections haven't that the operating system's socket table has filled, and new sockets can't be allocated.

    I have a possible solution, but I don't have anything to test it against. If you could provide a test case that reliably triggers the problem, I can debug it quickly and turn around a better answer.

    Meanwhile I have taken a guess at a solution, but you'll have to test it for me. If you can, please edit Client/Keepalive.pm (not Connection/Keepalive.pm). There should be a comment around line 582:

      # Build a connection object around the socket.

    I need you to add these three lines before that comment (wherever it may be):

    use Socket qw(SOL_SOCKET SO_LINGER); setsockopt($socket, SOL_SOCKET, SO_LINGER, pack("sll",1,0,0)) or die +( "setsockopt: $!" + );
    When it comes time to close that socket, it should not linger in FIN_WAIT_2.

    If that works for you, keep it free of charge. Also, let me know so I can include it in a future release.

    Thank you.

      it seems it helped but now I have another behaviour :)

      Script works well some time. Then I start to get "connect error 60: Operation timed out", see a lot of "TIME_WAIT" connections in netstat (and no other connections at all) in this moment. after few minutes all TIME_WAIT connections dissapear and I see empty output of netstat, but script still log "Operation timed out".

      I've turned on DEBUG in Client::Keepalive and got a lot of following messages at the time when netstat output is empty:

      ALLOCATE: enqueuing request for http:gdata.youtube.com:80 at /home/ser +vice/perl/lib/site_perl/5.8.8/POE/Component/Client/Keepalive.pm line +377. ... CON: request from session 5 for address 74.125.95.102 timed out at /ho +me/service/perl/lib/site_perl/5.8.8/POE/Component/Client/Keepalive.pm + line 507.

        I'm not sure I can debug this one from a distance. Can you provide a minimal test case to reproduce the problem? Ideally it would be something I can run without installing proprietary code or data.

        By the way, I released new versions of POE::Component::Client::Keepalive and POE::Component::Client::HTTP with a modified version of the SO_LINGER code and some other bug fixes.

Re: POE::Component::Client::HTTP, Keepalive, FIN_WAIT_2
by EvanCarroll (Chaplain) on Nov 26, 2008 at 05:09 UTC
    You can apparently change the time that a socket can remain in FIN_WAIT2 with a simple echo to /proc/sys/net/ipv4/tcp_fin_timeout. I'd be interested to know how POE handles a kernel reap of the socket.


    Evan Carroll
    I hack for the ladies.
    www.EvanCarroll.com

      I'm not sure I understand your question. Sockets in FIN_WAIT_2 have been closed at the application level. This often happens as a consequence of an IO::Handle object (or an instance of a subclass) being DESTROYed.

      Please clarify:

      • What do you expect an application to do with a closed socket?
      • How do you expect an application to call methods on a DESTROYed IO::Handle object?
      • What kernel syscalls do you expect to work with closed file descriptors?

      Thank you.