Background URL Session upload tasks retry even if server responds

Originator:ryanleeschneider
Number:rdar://31740364 Date Originated:2017-04-20
Status:Open Resolved:
Product:watchOS + SDK Product Version:
Classification: Reproducible:
 
I saw this thread in where you helped someone debug a watchOS background URL session issue:

https://forums.developer.apple.com/thread/70682

I believe we are hitting a similar issue.  I've included a summary of our issue below, and more details in radar #31740364, but am hoping you can answer:
 
- What was the resolution for iosmarkjim's radar #30553839?
- Any code-level changes we can make to change this behavior?
- If not, are there any mitigations?
 
We have a watchOS app that is using background URL Sessions and `scheduleBackgroundRefresh` to periodically schedule upload tasks to send sensor data to our servers for processing.
 
Everything works great in development and testing locally, however it's very clear from our server logs that some users' watch are getting into a state where they repeatedly send the same request to our server over and over, even though based on the server logs the server is responding with a 200 http status in a timely manner (less than 2 seconds).
 
The upload task's payload is multi-part form data, and I'm using some helper methods from Alamofire to generate the on-disk fileURL to upload, but am not using Alamofire for any actual traffic (in this code path, but it is used in other parts of the app).
 
The code for generating the upload task is:
 
            try mfd.writeEncodedData(to: fileURL)
            var request = try URLRequest(
                url: url,
                method: .post,
                headers: headers
            )
            let uploadTask = self.backgroundSession.uploadTask(
                with: request,
                fromFile: fileURL
            )
 
            uploadTask.resume()
 
Where `url` is the server endpoint and `fileURL` is the local multipart-form-data file generated using Alamofire's MultipartFormData class (instance mfd above).
 
The background session is configured like so:
 
      let backgroundConfigObject = URLSessionConfiguration.background(
        withIdentifier: "WatchBackgroundRefreshManager"
    )
    var backgroundSession: URLSession!
    var backgroundURLTask: WKURLSessionRefreshBackgroundTask? = nil
    override init() {
        super.init()
        backgroundConfigObject.sessionSendsLaunchEvents = true
        backgroundConfigObject.timeoutIntervalForRequest = 5.0 * 60.0
        backgroundConfigObject.timeoutIntervalForResource = 30.0 * 60.0
        backgroundSession = URLSession(
            configuration: backgroundConfigObject,
            delegate: self,
            delegateQueue: nil
        )
    }
 
NOTE: I have run this same code on the watchOS simulator included in Xcode Version 8.2 (8C38) and the experience seems to reproduce the issue 100%, in that even though the server responds w/ a 200 my delegate methods are never called and the simulator continues to hit the server every 15 seconds until the Resource timeout is hit.
 
Is there a way to get a system log from the watchOS simulator that might contain debug info on the url session behavior that I can attach to the radar?
 
I haven't yet reproduced the issue on an actual device, even if I introduce arbitrary lag on the development server, but can confirm it's happening on real devices in the wild based on server logs (examples are in the radar).

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!