WorkQueue
is a set of protocols that help to abstract code deferral. There are implementations to support RunLoop
, DispatchQueue
, OperationQueue
, NIO EventLoop
.
Swift has many code deferal mechanisms (as listed above). Unfortunately when library authors need to perform defered operations (e.g. typically for async methods), they have to make a choice as to whether to use DispatchQueue
, OperationQueue
, RunLoop
, etc.
However an application may be composed of many such libraries, where each author has chosen a different mechanism. This may lead to inefficient use of CPU resources. SwiftWorkQueue
aims to resolve this problem and allow the application developer to make the choice for their application.
Design goals:
- Allow library authors to have a generic representation of code deferral, so that application developers can make the decision as to which method they prefer
- A modular set of protocols supporting a variety of queue types, such as calling after a timeout.
Typically, when a library author needs to perform deferred operations, they decide the code deferal mechanism (e.g. DispatchQueue
). This will typically look like this:
import Foundation
class SomeObject {
private let dispatchQueue: DispatchQueue
init(dispatchQueue: DispatchQueue? = nil) {
// use a custom queue if one was not provided
self.dispatchQueue = dispatchQueue ?? DispatchQueue()
}
func someAsyncCall(_ completion: @escaping ()->Void) {
self.dispatchQueue.async {
// perform some sort of task in the background
completion()
}
}
}
To use WorkQueue
, the change for the library author is minimal:
import WorkQueue
import WorkQueueDispatch
class SomeObject {
private let workQueue: WorkQueue
init(workQueue: WorkQueue? = nil) {
// use a custom DispatchQueue if no WorkQueue was provided
self.workQueue = workQueue ?? WorkQueueDispatch(queue: DispatchQueue(label: "SomeObject default"))
}
func someAsyncCall(_ completion: @escaping ()->Void) {
self.workQueue.async {
// perform some sort of task in the background
completion()
}
}
}
Given the class above, the application developer can choose the deferal mechanism they want:
import WorkQueue
// application author will typically pick one of the following
import WorkQueueDispatch // To support DispatchQueue
import WorkQueueOperation // To support OperationQueue
import WorkQueueRunLoop // To support RunLoop
import WorkQueueNIO // To support NIO
class MyApplication {
let workQueue: WorkQueue
init() {
self.workQueue = WorkQueueRunLoop(runLoop: .main)
}
func run() {
SomeObject().someAsyncCall() {
// completion handler
}
}
}
Even though SomeObject()
's default deferal mechanism was to use a DispatchQueue
, in this case, the application author has chosen to use RunLoop
. .someAsyncCall()
and the subsequent completion handler will be called on the RunLoop
specified.
Add the SwiftWorkQueue
package to the dependencies within your application's Package.swift
file. Substitute "x.y.z" with the latest SwiftWorkQueue
release.
.package(url: "https://github.com/dannys42/SwiftWorkQueue.git", from: "x.y.z")
Add ClosureChain
to your target's dependencies:
.target(name: "example", dependencies: ["SwiftWorkQueue"]),
Add SwiftWorkQueue
to your Podfile:
pod `SwiftWorkQueue `
For more information visit our API reference.
This library is licensed under Apache 2.0. The full license text is available in LICENSE.