6

In this example I kick off 100 NSURLSessionDataTask at default priority but then set the last one to high priority. However it seems to have no effect at all as the last task still ends up running last.

NSURLSession *session = ...
NSURLRequest *request = ...

for (int i = 1; i<=100; i++) {
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSLog(@"%d", i);
    }];
    if (i == 100) {
        dataTask.priority = NSURLSessionTaskPriorityHigh;
    }
    [dataTask resume];
}

Why doesn't this task with high priority run before the other 99 at default priority? I would expect maybe a few of the earlier tasks might start to execute before the high priority task was even added, but not all of them.

I have even tried with HTTPMaximumConnectionsPerHost set to 1, makes no difference.

trapper
  • 10,375
  • 6
  • 31
  • 74

2 Answers2

8

The priority does not influence the priority on your app's side. It is a hint for the host to response to several requests in a priority. The host can completely ignore that.

To provide hints to a host on how to prioritize URL session tasks from your app, specify a priority for each task. Specifying a priority provides only a hint and does not guarantee performance. […]

[…]

You can specify or change a task’s priority at any time, but not all networking protocols respond to changes after a task has started. There is no API to let you determine the effective priority for a task from a host’s perspective.

Community
  • 1
  • 1
Amin Negm-Awad
  • 15,951
  • 3
  • 33
  • 50
  • So it looks like I completely misunderstood this. Priority has no effect on the queue order at all, a high priority task added last is going to be started last. It's completely useless lol – trapper Jun 19 '16 at 00:51
  • No, it isnot useless, because it is transmitted to the host. However, the host, not the client decides when data for a download is sent. – Amin Negm-Awad Jun 22 '16 at 18:02
  • But it's not transmitted to the host until the 100 low priority tasks have already been completed. Completely useless. So if I want something done with priority I need to use a seperate NSURLSession. – trapper Jun 23 '16 at 03:36
  • Again: *This* setting is for the host. It is meaningless, if the client never reaches it, because he decides to have another priority for scheduling the requests. It is not meaningless, but meaningless for what you want to do. – Amin Negm-Awad Jun 23 '16 at 04:04
  • I understand this setting is for the host. I just can't see any scenario where it has an actual use - hence useless. – trapper Jun 23 '16 at 04:43
  • 2
    You have multiple requests in parallel and want to tell the host, which request *he* should serve with a higher priority. Please keep in mind, that when the server sends much data, it is he decision which data to send first. In such case the client will receive the high priority data first. – Amin Negm-Awad Jun 23 '16 at 05:17
  • 1
    @AminNegm-Awad I have a question about this. I'm sniffing my requests with different NSURLSessionTaskPriority values. But I don't see any difference between them. (at least in HTTP layer) Do you know how this priority is transmitted to the host? – taichino Apr 12 '18 at 20:52
  • Without deeper knowledge I remember, that TCP/IP had precedence or QoS bits … But maybe this is not correct. For sure it depends on the protocol. – Amin Negm-Awad Apr 12 '18 at 21:36
0

Your server need to support HTTP/2.
NSURLSessionTaskPriority is a wrapper to HTTP/2 priority frames / dependency weighting.

NSURLSession's support of HTTP/2

Jirui
  • 129
  • 5
  • This may be true but it's not the answer to my issue. See the other answer above. – trapper Mar 17 '20 at 03:41
  • @trapper Actually, my answer explains why the *hint* not working. – Jirui Mar 17 '20 at 03:49
  • No sorry it doesn't, it was a client issue. The high priority task wasn't even attempted to start until the low priority tasks were all complete. – trapper Mar 17 '20 at 04:29