I'm experiencing some strange behaviour with my test app. I've about 50 simultaneous GET requests that I send to the same server. The server is an embedded server on a small piece of hardware with very limited resources. In order to optimize the performance for each single request, I configure one instance of Alamofire.Manager
as follows:
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
configuration.HTTPMaximumConnectionsPerHost = 2
configuration.timeoutIntervalForRequest = 30
let manager = Alamofire.Manager(configuration: configuration)
When I send the requests with manager.request(...)
they get dispatched in pairs of 2 (as expected, checked with Charles HTTP Proxy). The weird thing though is, that all requests which didn't finish within 30 seconds from the first request, get cancelled because of the timeout at the same time (even if they haven't been sent yet). Here is an illustration showcasing the behaviour:
Is this an expected behaviour and how can I make sure that the requests won't get the timeout before they are even sent?
Thanks a lot!
Yes, this is expected behavior. One solution is to wrap your requests in custom, asynchronous
NSOperation
subclass, and then use themaxConcurrentOperationCount
of the operation queue to control the number of concurrent requests rather than theHTTPMaximumConnectionsPerHost
parameter.The original AFNetworking did a wonderful job wrapping the requests in operations, which made this trivial. But AFNetworking's
NSURLSession
implementation never did this, nor does Alamofire.You can easily wrap the
Request
in anNSOperation
subclass. For example:Then, when I want to initiate my 50 requests, I'd do something like this:
That way, those requests will be constrained by the
maxConcurrentOperationCount
, and we don't have to worry about any of the requests timing out..This is an example
AsynchronousOperation
base class, which takes care of the KVN associated with asynchronous/concurrentNSOperation
subclass:There are other possible variations of this pattern, but just ensure that you (a) return
true
forasynchronous
; and (b) you post the necessaryisFinished
andisExecuting
KVN as outlined the Configuring Operations for Concurrent Execution section of the Concurrency Programming Guide: Operation Queues.