I am using a URLSession
setup this way:
public struct NetworkSession {
public var session: URLSession
public let sessionOperationQueue = OperationQueue()
public init() {
let sessionConfiguration = URLSessionConfiguration.default
sessionConfiguration.timeoutIntervalForRequest = 20
sessionOperationQueue.maxConcurrentOperationCount = OperationQueue.defaultMaxConcurrentOperationCount
sessionOperationQueue.qualityOfService = .userInitiated
session = URLSession(configuration: sessionConfiguration, delegate: nil, delegateQueue:sessionOperationQueue)
}
.....
}
I would like to observe the count of tasks found in the queue.
I tried using Combine:
sessionOperationQueue.publisher(for: \.operationCount).sink { count in
print("operations count: \(count)")
}
.store(in: &subscribers)
But that only prints 0
at init and never updates as requests start and complete.
How can I monitor the number of tasks found in the queue?
tl;dr
Observing the operation count on the session’s queue will not achieve what you want.
URLSession
code, the queue is used for the individual delegate methods, not to wrap the whole request-response.async
-await
rendition, the operation queue is not used at all (which is moot, given the previous observation).Bottom line, while
URLSession
has a method to inquire what pending requests are in progress, it does not, AFAIK, have an observable property for this (unless, of course, you abandon completion handlers and use only the delegate renditions). So, if you want to dynamically track of the count of pending requests, just keep track of this yourself. The asynchronous customOperation
subclass pattern seems like overkill (but is outlined in theOperation
section of this answer). It would be easiest to simply route all my network requests through a method that increments a counter as requests come in and decrements it upon completion.Long answer with code samples
You can use KVO to observe changes of the queue’s
operationCount
(see below), but that is not going to achieve what you want. This is not an operation that wraps the whole network request and response, but rather individual operations for the individual session delegate and completion handler callbacks.E.g., consider:
That produces:
Note, you never see it acknowledge that there are ten requests pending. The
operationCount
is reporting what’s on the delegate queue, which is not what you are looking for.By the way, in the above, the delegate queue is serial (as advised in the documentation). The very fact that it is a serial queue allowing concurrent network requests is further evidence that there is not an operation wrapping the whole request, but rather is for the individual delegate callbacks.
As an interesting aside, if you use the new
async
-await
URLSession
methods, the operation queue is not used at all. That makes sense (given that it is using the new concurrency system), but it is not noted in the documentation at this point. Anyway, the below will does not trigger any operation count changes:But this is moot, given that the
URLSession
operation queue does not achieve what you want, regardless.