My current guess: This is a bug in how the socket is set up or one of the underlying libraries.

Using the stream debug hooks indicates the failure is due to "readLine" returning an empty line when parsing the request header. I cannot tell if an empty line is returned due to an actual 0 byte return from read/recv or some processing of the read data. Still, this would indicate the HTTP library considers the request to be malformed.

The question is then: Are the requests from JMeter malformed?

A wireshark capture was performed of the JMeter test traffic. This wireshark data indicated 5000 HTTP requests were made. Which is what JMeter produced. All 5000 of these requests were byte identical. This capture did not affect the test results: A similar number of requests failed.

I tried to instrument the read/recv calls using dtrace. This indicated read, and not recv, was used when reading from teh socket. I was unable to determine anything else tho. Probably a better idea to instrument HTTP library a bit more.

Cheers,
Corey



-Corey O'Connor
coreyoconnor@gmail.com
http://corebotllc.com/


On Tue, Nov 5, 2013 at 6:10 PM, Corey O'Connor <coreyoconnor@gmail.com> wrote:
I've updated the code to handle persistent connections. As best I can figure anyways..
Unfortunately this does not resolve the issue. The server still reports the connection being closed before the full response is read.

The test is done via JMeter. See the perf_test.jmx file. I've confirmed JMeter is include "connection: close" headers in all requests. Which means the persistent connection code is not even being exercised. From instrumenting the code I can confirm this is the case: All requests include "connection: close" and the client never performs a second request using the same stream.

An additional data point: The same test when run with 1 capability (EG: +RTS -N1) does *not* fail. There are no connection close errors. Only when running with multiple capabilities does the test fail.

Cheers,
Corey

On Tue, Oct 22, 2013 at 4:54 PM, Corey O'Connor <coreyoconnor@gmail.com> wrote:
On Mon, Oct 21, 2013 at 7:28 PM, Joey Adams <joeyadams3.14159@gmail.com> wrote:
On Mon, Oct 21, 2013 at 5:15 PM, Corey O'Connor <coreyoconnor@gmail.com> wrote:
Curiously: If the Network.HTTP.close is removed the server does not fail, but some requests takes several seconds to process. I presume the ordering of effects is then correct, but without the explicit close the close occurs only a GC time.

The client may be trying to reuse the connection; see http://en.wikipedia.org/wiki/HTTP_persistent_connection.  This seems consistent with your results:

 * With the close call: connection is closed right after client sends a second request, so client whines.
 * Without the close call: client waits around for a response, then gives up and establishes another connection.

To confirm, add another receiveHTTP call client_interact and see if it returns another Request.

​Thanks!​ I'll try your test and see if anything changes.

Though I thought the code accounted for this: A connection close header is added to each response. Which I thought would cause the client to close the connection.​​ I could be totally wrong tho. There could be some additional aspect of HTTP connections I do not understand.

Properly supporting persistent connections should be pretty easy. There is another Network.HTTP server package that does this: http://hackage.haskell.org/package/http-server-1/docs/Network-HTTP-Server.html

So I'll give that a shot and report back.

Thanks!
Corey