[PATCH] LWPng-alpha-0.24: 180 second delay
Paul Walmsley (shag@booyaka.com)
Thu, 11 May 2000 02:54:25 -0500 (CDT)
When using pipelined requests with multiple connections with
LWPng-alpha-0.24, it is possible for LWPng to block waiting for data to
arrive on a connection that no requests have been transmitted across.
This bug causes the unsuspecting code to block for 180 seconds in the
LWPng event loop, and causes an extra HTTP teardown/setup cycle when LWPng
shuts down the "inactive" connection.
The specific situation that caused this problem is as follows:
1. Client configures LWPng to use 2 parallel connections to the HTTP
server, to issue up to 100 persistent requests per connection, and to
allow 3 outstanding pipelined requests per connection.
2. Client issues three HTTP GET requests at a remote server (running
Apache 1.3.6)
3. LWPng opens up two HTTP connections to the remote server and issues all
three requests down connection #1.
4. Server returns a response for the first request and then closes
connection #1.
5. LWPng blocks in select() waiting for data to arrive on connection #2.
Since no requests were issued down connection #2, this select() times
out after waiting for 180 seconds. <-- ERROR
6. LWPng closes connection #2, opens a new connection #3, and issues the
remaining two requests down connection #3. The server disconnects
again after transmitting the first of these two requests, but LWP
opens a new connection #4 immediately and finishes the last request.
At first, the server's behavior struck me as a possible HTTP server
implementation bug. But the server does return a "Connection: close"
header along with the response, and section 8.1.4 of RFC 2616 states:
A client, server, or proxy MAY close the transport connection at
any time.
...
So with the patch below, LWPng will immediately reschedule the 'orphaned'
requests across the remaining connection. The patch cuts the wallclock
time for my program to fetch three URLs from 187 seconds down to 7
seconds, and avoids the extra TCP shutdown and connect.
Comments welcome and appreciated.
- Paul
--- lib/LWP/Server.pm.old Mon Apr 12 08:27:53 1999
+++ lib/LWP/Server.pm Thu May 11 02:18:21 2000
@@ -276,9 +276,11 @@
$self->create_connection
} else {
$self->done;
}
- }
+ } else {
+ $self->activate_connections;
+ };
}
sub done # this really just deallocates this LWP::Server entry
{