Timeout interval not set for POST requests on iOS - ios

I have a timeOutInterval set to 30 seconds on all my requests via this code:
class DefaultAlamofireSession: Alamofire.Session {
static let shared: DefaultAlamofireSession = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30
configuration.timeoutIntervalForResource = 30
return DefaultAlamofireSession(configuration: configuration)
}()
}
While testing, I noticed that only my GET requests get timed out at 30 seconds. My POST requests are still using the default interval which is 60 seconds.
Can anyone explain why and possibly tell me how I can make the POST requests also time out at 60 seconds?
Thanks a lot,
Paprika

URLSessionConfiguration.timeoutIntervalForRequest does not do what you think it does. From Apple's docs:
This property determines the request timeout interval for all tasks within sessions based on this configuration. The request timeout interval controls how long (in seconds) a task should wait for additional data to arrive before giving up. The timer associated with this value is reset whenever new data arrives. When the request timer reaches the specified interval without receiving any new data, it triggers a timeout.
So that property only controls the timeout between chunks of response Data. That's not typically what you want. Instead, you want to set the URLRequest.timeoutInterval directly, which does more of what you want.
If during a connection attempt the request remains idle for longer than the timeout interval, the request is considered to have timed out. The default timeout interval is 60 seconds.
As you can see, this timeout applies to the connection attempt, which is what most people think of as a request's timeout.
You can customize this value in Alamofire by applying a RequestAdapter to your custom Session. Or, you can use the requestModifier closure that available on the various request* methods.

Related

URLRequest fails before timeout

I want to set different timeouts for different requests. My request routine looks like:
var request = URLRequest(url: url,
cachePolicy: .reloadIgnoringLocalCacheData,
timeoutInterval: timeout)
// setting headers and body...
sessionTask = localURLSession.dataTask(with: request)
sessionTask?.resume()
where localURLSession is defined as public var:
public var localURLSession: Foundation.URLSession {
return Foundation.URLSession(configuration: localConfig, delegate: self, delegateQueue: nil)
}
public var localConfig: URLSessionConfiguration {
let res = URLSessionConfiguration.default
res.timeoutIntervalForRequest = Self.ordinaryRequestsTimeout // 20 seconds
return res
}
Then I have 2 problems:
When I make 2 simultaneous requests with 100% loss Network Link
Conditioner (first with 20 seconds timeout and second – with 40
seconds), both requests fails after 8 seconds. I don't understand
why.
When I make one request for the first time with 100% loss
Network Link Conditioner, it fails in timeout like expected, but
retrying this request fails in 1 second. I want to wait all the
timeout every time.
In all likelihood, for the 8-second failure, the DNS request is timing out, so you aren't connecting at all.
For the 1-second failure, the OS has probably concluded that the host is unreachable, and won't even try again until the network changes or it successfully makes at least one request to some host somewhere (negative DNS caching).
That said, without a packet trace, I can't be certain of either of those statements.

Different timeouts in one URLSession

Is it possible to set different timeouts intervals per URLRequest using one URLSession?
I tried to set
urlRequest.timeoutInterval = 20 * 60
but it has been ignored by URLSession and request failed after default 60 sec with timeout error.
Only this setup change timeouts:
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 20 * 60 // 20 min
self.session = URLSession(configuration: configuration)
but 20 * 60 // 20 min is applied to all URLRequest in that session.
I want to allow some tasks to wait longer for response but rest of them should default failed after default 60 sec.
Is is possible? Or should I use more than one URLSession
PS. During research I found this bug:
https://bugs.swift.org/browse/SR-2680
You can have configure the timeout for each individual URL. It's just that you can't set a timeout that is bigger than the URLSession's configuration itself.
In some cases, the policies defined in this configuration may be
overridden by policies specified by an NSURLRequest object provided
for a task. Any policy specified on the request object is respected
unless the session’s policy is more restrictive. For example, if the
session configuration specifies that cellular networking should not be
allowed, the NSURLRequest object cannot request cellular networking.
Docs on URLSessionConfiguration
The default timeout is 60 seconds. You're setting to 1200 which is bigger. So it doesn't work. Increase your configuration and then you can configure each url's timeout differently.
Modifying a URLSession's properties after it has been assigned to a URLSession isn't supported, per Apple's documentation. You need to create the configuration separate and initialize a separate instance with it.

TimeoutInterval in Alamofire

If I set an 5 mins timeout interval for Alamofire request like below, it means an individual/overall API sync would take 5 mins?
sessionConfiguration.timeoutIntervalForRequest = 300
self.defaultManager = Alamofire.SessionManager(configuration: sessionConfiguration, serverTrustPolicyManager: policyManager)
No, it means that max time for timeout response is 300 seconds. If API finishes earlier you won't have to wait that much.
Regarding second question - it depends on your backend. For most cases 60 seconds is more then enough, however if you have any call that exceed it then you need to increase it. Note that it doesn't take parsing time into the consideration, just getting response from server. If you have large object that needs x minutes to parse but get it in 50 seconds it will be fine.
The main reason for timeout is because your server might never response and instead of letting your app hang, you can handle timeout error somehow.

Alamofire slowing down on each request

I am using Alamofire to do a basic requests to an API endpoint. I noticed that the more often I do these tests, the longer the Alamofire request seems to take.
I can reproduce this behaviour with the code sample below. This does a bunch of requests and prints the duration of the request to the console. The last request is about .5 seconds slower than the first one. The amount of slow down seems to be related to the amount of JSON the API returns (our API returns much more data and the slow down is much more significant)
Am I hitting some kind of caching mechanism here?
let testURL = "https://httpbin.org/get"
for var i = 0; i < 100; i++ {
let startDate = NSDate()
Alamofire.request(.GET, testURL)
.responseJSON { response in
print("Duration of request: \(NSDate().timeIntervalSinceDate(startDate))")
}
}
The problem here is not Alamofire, but how you are measuring the latency. You are queueing 100 requests, so the time it takes for each is very small. But since they are queued up, when the last request runs, will depend on the majority of previous requests finishing.
You should use the request timeline object to obtain the latency, with
request.timeline.totalDuration, for example.

How does parse response when there is more request then the limit?

I am working in implementing of parse service.
Suppose we have a free account of parse. So it allow us to send 30 Request/Second.
What happen if there is 40 request sent each second.
will parse respond to 10 request after the 30 request completed or will it reject that request?
if it respond to 10 request after the first 30 and same thing happen for continues 2 min then we have 10 * 120 = 1200 request pending. What happen in this scenario ?
If Prase service going to reject due to this reason(like more request then the limit) then how does we get to know this reason. Is there any error code for this rejection?
From this post:
https://parse.com/questions/getting-this-application-has-exceeded-its-burst-limit-code-155-any-idea
seems that any additional call that exceed the burst limit, will return an error like this:
{"code":155,"error":"This application has exceeded its burst limit."}

Resources