I would like to exactly understand how NSURLSession schedules it's tasks internally.
I create a session (with -defaultSessionConfiguration) in my app and set it's HTTPMaximumConnectionsPerHost = 1. To my knowledge this is the only way to throttle the amount of tasks executing in parallel. Kinda breaks apart if you actually wanna have a hard per session limit (becuase of arbitrary CDN-host redirects) but we'll ignore this for a moment.
Now, when I have this limit set to 1 and "queue up" (i.e. create and -resume), say, 50 download tasks I would expect one task at a time to be executed, one after another. However, what I am observing (in Charles) is that actually ALL tasks are being started immediately. In my case this results in a 302 redirect to a CDN, so following this a more or less arbitrary amount of tasks actually proceeds, depending on the amount of different CDN hosts in the redirects.
Now the next problem is that, since all requests actually started already, the ones coming later in the queue time out easily, unless I change timeoutIntervalForResource on my session configuration to something basically large enough to finish ALL downloads, and not only one. Actually, timeoutIntervalForRequest needs to be set to the same value for things to work, presumably because all tasks actually start at the same time.
This seems like really weird behavior to me. Why does NSURLSession start all -resumed tasks immediately (afterwards just now actually downloading data, but beginning to count each request's timeout) instead of only actually starting a new task, once another one has finished and HTTPMaximumConnectionsPerHost actually allows for a new request to start? Is this really generally expected behavior or am I doing something wrong / understanding something wrong here?
I would not expect having to set timeoutIntervalForRequest to some really high value in my case, since I am expecting each of the 50 tasks to start their request one after another, never opening more than (ideally 1) request at a time. So that the timeout really only starts counting once all the previous downloads have finished.
Running the same code with a background session configuration interestingly works without timeout problems. I assume that is because timeoutIntervalForResource is supposedly set to 1 week by default and request timeouts are just silently caught and then rescheduled?