General questions about persistent connections

145 views
Skip to first unread message

Mike

unread,
Feb 4, 2011, 12:39:30 PM2/4/11
to ASIHTTPRequest
Hello,

I've been having problems with persistent connections. I flipped on
DEBUG_PERSISTENT_CONNECTIONS (thanks to the authors for that -- it's
really helpful) and it brought up some questions:

1. The debug info is suggesting that if a connection is used, it is
set to expire in 20 seconds (in my case -- 60 by ASI default). And
then if that connection is reused within that 20 seconds, the expiry
is reset back to 20. Is this how persistent connections are meant to
work? Would a connection remain open for an hour provided there are
requests constantly using it? Or does the remote server close it?

2. Is there a maximum number of connections setting? I can't find
one. The internet suggests that a client should only maintain two
connections with the server but I'm not sure this is being honoured.

Thanks to anyone who can answer. I did read a nice thread between Ben
and Jimmy about persistent connections that helped, so thanks to Ben
for that.

Mike


Joseph Heenan

unread,
Feb 5, 2011, 7:03:35 AM2/5/11
to asihttp...@googlegroups.com
Hi Mike,

On 04/02/2011 17:39, Mike wrote:
> 1. The debug info is suggesting that if a connection is used, it is
> set to expire in 20 seconds (in my case -- 60 by ASI default). And
> then if that connection is reused within that 20 seconds, the expiry
> is reset back to 20. Is this how persistent connections are meant to
> work? Would a connection remain open for an hour provided there are
> requests constantly using it? Or does the remote server close it?
>

It could be possible for the connection to stay open for an hour I
believe, if you're making requests at least every 20 seconds.

Are you thinking this could be an issue?

Some servers will close the connection before that - eg. Apache has a
MaxRequestsPerChild, which defaults to 10,000 in the current builds I
believe, but was lower in older versions and can be configured by the
server admin. The time the server will allow the connection to remain
idle is also configurable.

> 2. Is there a maximum number of connections setting? I can't find
> one. The internet suggests that a client should only maintain two
> connections with the server but I'm not sure this is being honoured.
>

I use this:

[[ASIHTTPRequest sharedQueue] setMaxConcurrentOperationCount:2];

If you're not using the shared queue, or are using multiple queues,
you'll need to modify that.

Joseph

Ben Copsey

unread,
Feb 5, 2011, 7:59:06 AM2/5/11
to asihttp...@googlegroups.com
Hi Mike

> I've been having problems with persistent connections

I fear you're not the only one - I can't think of another ASIHTTPRequest feature that's caused more confusion... :)

>> 1. The debug info is suggesting that if a connection is used, it is
>> set to expire in 20 seconds (in my case -- 60 by ASI default). And
>> then if that connection is reused within that 20 seconds, the expiry
>> is reset back to 20. Is this how persistent connections are meant to
>> work? Would a connection remain open for an hour provided there are
>> requests constantly using it? Or does the remote server close it?
>>
> It could be possible for the connection to stay open for an hour I believe, if you're making requests at least every 20 seconds.

I think it would depend on how the server implements persistent connections, but broadly speaking, yes.

The behaviour of persistent connections seems to vary widely between servers. Apache has a sensible system for handling persistent connections, which primarily involves two things:

* The number of times a connection can be reused for a request (defaults to 100)
* The number of seconds a connection will stay open for while idle (defaults to 5)

Apache is helpful enough to send clients this information in the Keep-Alive header (I think nginx does this too). This means that ASIHTTPRequest can adapt its behaviour according to what the server tells it to do with the connection.

Unfortunately, Keep-Alive is not part of the HTTP standard, so many web servers don't send it. The HTTP RFC has information on how clients should handle a closed connection (http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html), but unfortunately CFNetwork does not expose the underlying connections used by HTTP requests in the public APIs, so ASIHTTPRequest can't always deal with this in a sensible fashion. If ASIHTTPRequest encounters a stream error that looks like a closed connection, it will attempt to retry the request on a new connection. This doesn't always work though, as with some servers you just get timeouts.

>> 2. Is there a maximum number of connections setting? I can't find
>> one. The internet suggests that a client should only maintain two
>> connections with the server but I'm not sure this is being honoured.
>>
> I use this:
>
> [[ASIHTTPRequest sharedQueue] setMaxConcurrentOperationCount:2];
>
> If you're not using the shared queue, or are using multiple queues, you'll need to modify that.

Just to clarify on Joseph's suggestion - the sharedQueue is used for all requests started with startAsynchronous.

For anyone else finding this, the tricks for persistent connections are:

1) If you can configure your server to send a keep-alive header, do so. This should solve 99% of all problems.
2) If not, try to find out how the server handles timing out connections. If it manages them on the basis of the number of seconds idle, set persistentConnectionTimeoutSeconds accordingly, and you should see much more reliable behaviour. If this doesn't seem to be documented for your server, you can usually make an educated guess based on the output from DEBUG_PERSISTENT_CONNECTIONS, as Matt has done.
3) Disable persistent connections for requests with a body (eg POST or PUT)
4) If all else fails, disable persistent connections.

I think I will add this to the documentation. :)

Best,

Ben

Mike Aleksiuk

unread,
Feb 6, 2011, 2:41:36 PM2/6/11
to asihttp...@googlegroups.com
Hi Ben and Joseph,

First of all, those are great answers and info. Thanks to both of
you. I have one question about the tricks that Ben mentioned.

> For anyone else finding this, the tricks for persistent connections are:
>
> 1) If you can configure your server to send a keep-alive header, do so. This should solve 99% of all problems.
> 2) If not, try to find out how the server handles timing out connections. If it manages them on the basis of the number of seconds idle, set persistentConnectionTimeoutSeconds accordingly, and you should see much more reliable behaviour. If this doesn't seem to be documented for your server, you can usually make an educated guess based on the output from DEBUG_PERSISTENT_CONNECTIONS, as Matt has done.
> 3) Disable persistent connections for requests with a body (eg POST or PUT)
> 4) If all else fails, disable persistent connections.

I've ended up going with trick #3/#4 for now because it's working, but
I'm curious why you recommend this for POST/PUT. Does your
recommendation hold even if the body is very small?

Just in case there's interest: My problem is similar to what you would
see if the server says Keep-Alive is 20 seconds but is actually
closing connections at 10 or so seconds. ASIHttpRequest tries to use
a connection well within the 20 second boundary (at about the 12 or 13
second mark) but it fails. This might very well be the server's fault
and until I can setup my own test server and get more info, I'm going
to drop the issue. Debug output suggests ASI is doing the right
thing.

Thanks again for the connection info.

Mike

Reply all
Reply to author
Forward
0 new messages