nsurlsessiond disconnects on queuing several upload tasks

Good Morning, wondering if i can get some help regarding nsurlsession behaviour on the case mentioned in the title.

I'm trying to enqueue several upload tasks to a background session created from configuration:

discretionary=false
sessionSendsLaunchEvents=true
waitsForConnectivity = true

The app delegate is handling the finish of all tasks with

handleEventsForBackgroundUrl

The session delegate is implemented with:

didCompleteWithError
didSendBodyData
DidFinishEventsForBackgroundSession

The NSURLSessionUploadTask tasks are being enqueued to the background session with task.resume(). Each NSURLSessionUploadTask is attached with a NSURLRequest with a body content populated from a file (in device memory - app documents folder).

Each file is around 20-odd Mb.

This all works fine if i do a couple of tasks. When i want to attach dozens of tasks to the background session nsurlsession connection gets invalidated and terminated (we ultimately want up to hundreds... but i do understand nsurlsession should cope with up to thousands).

Error (639) (CFNetwork): BackgroundSession  connection to background transfer daemon interrupted
Error (639) (CFNetwork): BackgroundSession connection to background transfer daemon invalidated

The daemon does restart but the upload tasks will then all fail with:

Error Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service"

The nsurlsessiond daemon does not warn of any crash or warning that is about to crash but then again i can't be sure given that the log probably only makes sense to the team responsible for nsurlsession dev. An example timeframe log of nsurlsessiond around a connection invalidated/terminated is attached.

FYI and completion i've tested in different xcode versions (12.3,12.5) and different iOS versions.

Is there any limitations on size of tasks when enqueuing to background session N (dozens) number of tasks ? Am i missing any major handling of nsurlsession/configuration parameter?

Happy to provide more info if necessary.

Best Regards

Do you see a crash report generated for nsurlsessiond?

If you look in the system log, do you see nsurlsessiond change process ID (pid)?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Good afternoon Quinn. Thanks for your answer and attention on this.

The nsurlsessiond process does not show any crash (that i can tell from logs) but it does crash the connections on all processes depending on background sessions including my app.

The nsurlsessiond does change PID when it restarts. For example I've just replicated the case and it changed from '1242' to '1452'.

I forgot to mention in the original post: the file streams being attached to the request body of each task are of 2X Mb/each and the frequency of task.resume() calls is around 1 per second.

Please see attached the system log around the time it happens. You can see that more processes like dasd,geod, ... lose the connection to the nsurlsessiond. Two observations from this and my app log:

  1. I do see some mentions to my app id ('com.novarumdx.PMF-Data-Collector') i haven't noticed before on wifid and symptomsd but i cant make much sense of them!
  2. the UIKitCore of our app log starts throwing 'Received memory warning' after the background session is invalidated/terminated.

The nsurlsessiond does change PID when it restarts.

OK. This confirms that something has caused nsurlsessiond to terminate, which explains the NSURLErrorBackgroundSessionWasDisconnected error.

It does not help us understand why it terminated, but it’s enough evidence to justify you filing a bug about this. When you file your bug:

  • Attach a sysdiagnose log. The system log snippets you’ve posted here aren’t sufficient to debug problems like this.

  • It would be great if you could attach a test project that reproduces the problem, but I realise that might not be feasible. If not, include instructions on how to reproduce it with your real app.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn, i'll raise that as soon as i possible can.

Before i do that, could there be influence of the NSMutableUrlRequest itself in this? ie the format, headers used, etc...? Reason why i ask is because i'm building the request structure myself (multipart) and using uploadTaskWithStreamedRequest:

Could there be a root cause in this?

To be clear, nsurlsessiond should never crash no matter what you do. As a system-wide service, it’s expected to protect itself from client ‘abuse’.

Having said that, this won’t work:

Reason why i ask is because i'm building the request structure myself (multipart) and using -uploadTaskWithStreamedRequest:

You can’t use a streamed request in a background session because the stream request requires that your app be running and the whole point of using a background session is that the request can run while your app is suspended (or terminated).

If you find that your streamed request is what’s causing nsurlsessiond to crash, that’s definitely bugworthy.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn. You've confirmed my suspicions. Yesterday i refactored everything to use uploadTaskWithRequest:fromFile: and all works smoothly now (tested up to 100+ files).

Could you clarify if it's safe to use the same file as "buffer" (rather than several) before enqueuing the task to the session even if the enqueuing happens very quickly? i guess in other words - is it thread safe?

Just FYI and completion: I actually have it working with uploadTaskWithStreamedRequest: because the request and files do go up (even with app in background) but this only happens on <10ish tasks. It's just down to nsurlsessiond not coping with several of them being enqueued in a short period of time. That would happen even if the app was on foreground and therefore running at all time.

I will raise the bug, don't worry. It's just that i've been hiding i'm doing Xamarin.iOS so i just need to find the (free) time to convert to native so the bug is more complete considering your advice on reporting.

Yesterday i refactored everything to use -uploadTaskWithRequest:fromFile: and all works smoothly now (tested up to 100+ files).

Yay!

Could you clarify if it's safe to use the same file as "buffer" (rather than several) before enqueuing the task to the session even if the enqueuing happens very quickly?

To what end? What are you trying to achieve by this?

Last I checked nsurlessiond used copy-on-write (that is, clonefile, see its man page) to isolate avoid taking up extra disk space while isolating itself from changes made by the client, but it’s not something I’m particularly comfortable recommending.

I will raise the bug, don't worry.

Thanks.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Yay!

Thanks for your help and leading me away from stream!

To what end? What are you trying to achieve by this?

The purpose is to save storage. I wanted to avoid creating unique body/zip files (which is what we are uploading) for each zip file we want to upload. I've tried it and i can create the same body and zip file just before enqueuing to the session. I was skeptical on doing this because the requests are enqueued very fast (one or more per second) but it does work. I think it's related with what you mention regarding copy-on-write.

Again, thank you for your support and answers.

I am facing same problem. I got below error when trying to upload multiple images using background session configuration. Any help is appreciated. I am using uploadTask(with: request, fromFile: URL(fileURLWithPath: path)) for uploading images to server. These all things work fine if i upload 10 or less images at a time. But if i try to upload more tuan 10 then i got below errors.

BackgroundSession <17817097-9127-45A7-B9C2-17145F5FD17F> error requesting a NSURLSessionUploadTask from background transfer daemon: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service with pid 65435 named com.apple.nsurlsessiond was interrupted, but the message was sent over an additional proxy and therefore this proxy has become invalid." UserInfo={NSDebugDescription=The connection to service with pid 65435 named com.apple.nsurlsessiond was interrupted, but the message was sent over an additional proxy and therefore this proxy has become invalid.

It’s probably best to start a new thread for this. Use the same tags as this thread so that I see it.

Also, look for nsurlsessiond crash reports and, if you see one, add it to your post, using the instructions in Posting a Crash Report.

Feel free to post a link to your new here so that folks can follow the conversation.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

nsurlsessiond disconnects on queuing several upload tasks
 
 
Q