AsyncSerialQueue
is a library provides some useful patterns using Swift Concurrency:
AsyncSerialQueue
is a class provides serial queue-like capability using Swift Concurrency. Tasks placed in an AsyncSerialQueue
are guaranteed to execute sequentially.
AsyncCoalescingQueue
is a companion class that has properties similar to DispatchSource.
AsyncSerialQueue is currently only available on Apple platforms (i.e. not on Linux). This is because of the need for locking and Swift currently does not have a standard cross-platform locking mechnism.
let serialQueue = AsyncSerialQueue()
func example() {
serialQueue.async {
print("1")
}
serialQueue.async {
print("2")
}
serialQueue.async {
print("3")
}
print("apple")
}
Note that example()
does not need to be declared async
here.
The numbers will always be output in order:
1
2
3
However, there is no guarantee where apple
may appear:
apple
1
2
3
or
1
2
apple
3
or any other combination
There may be some cases (e.g. unit tests) where you need to wait for the serial queue to be empty.
func example() async {
serialQueue.async {
print("1")
}
await serialQueue.wait()
serialQueue.async {
print("2")
}
}
example()
will not complete return 1
is printed. However, it could return before 2
is output.
Similarly, if looking for something similar to barrier blocks:
func example() async {
serialQueue.async {
print("1")
}
await serialQueue.sync {
print("2")
}
serialQueue.async {
print("3")
}
print("apple"")
}
In this case, apple
will never appear before 2
. And example()
will not return until 2
is printed.
The following code:
let coalescingQueue = AsyncCoalescingQueue()
coalescingQueue.run {
try? await Task.sleep(for: .seconds(5))
print("Run 1")
}
coalescingQueue.run {
try? await Task.sleep(for: .seconds(5))
print("Run 2")
}
coalescingQueue.run {
try? await Task.sleep(for: .seconds(5))
print("Run 3")
}
coalescingQueue.run {
try? await Task.sleep(for: .seconds(5))
print("Run 4")
}
coalescingQueue.run {
try? await Task.sleep(for: .seconds(5))
print("Run 5")
}
Will output the following:
Run 1
Run 5
And take 10 seconds to complete executing.