Re: Spoon-feeding NSURLConnection
Re: Spoon-feeding NSURLConnection
- Subject: Re: Spoon-feeding NSURLConnection
- From: Josh Graessley <email@hidden>
- Date: Wed, 27 Jun 2012 13:12:10 -0700
I don't have a workaround, but I do have something that might help shed light on what's going on. CFNetwork supports additional logging to debug problems at that layer. You can set the CFNETWORK_DIAGNOSTIC environment variable when starting your process to enable extra debugging.
CFNETWORK_DIAGNOSTIC=1
Enables internal CFNetwork event and state logging
CFNETWORK_DIAGNOSTIC=2
Adds information about how CFNetwork decides to make and re-use TCP sockets
CFNETWORK_DIAGNOSTIC=3
Adds decrypted bytes in and out - this one is dangerous and should be used with caution.
These are covered very briefly in a 2012 WWDC session (videos online) titled Networking Best Practices.
-josh
On Jun 27, 2012, at 12:33 PM, Jens Alfke <email@hidden> wrote:
> Alright, I think I've figured out what's wrong … and if I'm right, it's a CFNetwork bug. :( Now I need help figuring out a workaround.
>
> First, I can reproduce the problem myself, using a server on localhost. So it has nothing to do with packet loss or firewalls or anything like that. Running HTTPScoop (sort of like tcpdump, only comprehensible to dummies like me) filled in most of the rest of the details.
>
> What's unusual about my scenario is that TouchDB has a connection to the server's "_changes feed", listening for database changes. This feed is an HTTP resource but it uses a "long poll" or "hanging GET" — I send a GET to it, and the server doesn't send back a response until it has data to send. So the connection is expected to stay open for an indefinite time.
>
> The problem is that CFNetwork appears to be scheduling one of the other GETs on the same socket as the _changes feed connection. And since the _changes feed connection never closes (until some future time when a change occurs on the server), that means the other request gets stuck. Eventually it times out.
>
> As an experiment, I altered the query parameters on the _changes feed URL to request a 10-second timeout ("&timeout=10000"). With this change, the server sends an empty response after 10 seconds … and *one millisecond* later the stuck GET connection notifies the delegate that it got a response and gives it the data.
>
> So if my hypothesis is right, there seems to be a big flaw in CFNetwork's algorithm that assigns HTTP requests to TCP sockets. It's assigning them too early, queuing a request on a busy socket and then leaving it waiting there even after other sockets finish their requests and become available. This is very bad if one request is a "hanging GET", but equally bad in more common cases like an extremely long download.
>
> What I'd like to do is make some kind of change to the hanging-GET NSURLRequest that will make CFNetwork give it its own socket without keep-alive. Then nothing will get queued behind it. But I'm not sure how to do such a thing on the client side. Any ideas?
>
> (And yes, my next action is going to be to file a Radar on this.)
>
> —Jens
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden