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.
URLSessioncode, the queue is used for the individual delegate methods, not to wrap the whole request-response.async-awaitrendition, the operation queue is not used at all (which is moot, given the previous observation).Bottom line, while
URLSessionhas 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 customOperationsubclass pattern seems like overkill (but is outlined in theOperationsection 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
operationCountis 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-awaitURLSessionmethods, 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
URLSessionoperation queue does not achieve what you want, regardless.