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.