|Problems? Is your data what you think it is?|
Timing out POE http clientby ryantate (Friar)
|on Mar 28, 2006 at 23:00 UTC||Need Help??|
ryantate has asked for the wisdom of the Perl Monks concerning the following question:
There are plenty of great examples of building HTTP clients with POE. For starters, merlyn's Oct 2002 LinuxMag piece, a section of the POE Cookbook and even a post here on Perlmonks by POE creator Rocco Caputo.
If that weren't enough, the dang thing can download 27 Web pages in less than three seconds.
But there's one weakness to POE::Component::Client::HTTP no one seems to mention, which is that is cannot time out Web connections. In fact, while timeouts are seemingly utlized in many of the above examples, the current http client docs explicitly state, under a BUGS section at the very end:
The following spawn() parameters are accepted but not yet implemented: Timeout.
Instead, what the POE http client does is trigger the "response" event for each session within the timeout period, but does not close out a session until the http connection is actually closed. So $poe_kernel->run will not return until all http sessions are done, even if the timeout is well past.
My question: What is the best way to enforce a timeout on POE::Component::Client::HTTP such that $poe_kernel->run will return at or very near the timeout period, instead of many seconds later?
The only solution I have is to call $kernel->stop within the response handler when the last session response is done. But the stop method is experimental and has some serious caveats.
Some examples of POE::Component::Client::HTTP timeout in action:
The script (poe_delay.pl):
Now if we run the above script with a timeout of 5 seconds, $kernel->run does not return until well after the responses are all in:
If we increase the timeout to 20, we see that the responses and $kernel->run finish at the same time. This is because all HTTP connections are closed within 20 seconds, I believe:
Finally, if we uncomment the $kernel->stop line inside sub response_handler in the above script, we get: