Skip to content

Instantly share code, notes, and snippets.

@brennanMKE
Last active July 1, 2021 23:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brennanMKE/e29e6d305cf03978b9f9e084296f2124 to your computer and use it in GitHub Desktop.
Save brennanMKE/e29e6d305cf03978b9f9e084296f2124 to your computer and use it in GitHub Desktop.
Breaking async code in Swift
import PlaygroundSupport
import Foundation
class Worker {
private let queue = DispatchQueue.global(qos: .background)
private let serialQueue = DispatchQueue(label: "com.acme.serial")
public private(set) var count = 0
func incrementCount() {
serialQueue.sync {
count += 1
}
}
func work() {
let workItem = DispatchWorkItem() { [weak self] in
guard let s = self else { return }
s.incrementCount()
print("πŸ”΅ Work [\(s.count)]")
}
queue.async(execute: workItem)
workItem.wait()
}
}
let worker = Worker()
let queue1 = DispatchQueue(label: "com.acme.queue1", attributes: .concurrent)
let queue2 = DispatchQueue(label: "com.acme.queue2", attributes: .concurrent)
let queue3 = DispatchQueue(label: "com.acme.queue3", attributes: .concurrent)
let range = 0..<5
queue1.async {
range.forEach { _ in
worker.work()
print("πŸ”΄ Done [\(worker.count)]")
}
}
queue2.async {
range.forEach { _ in
worker.work()
print("πŸ”΄ Done [\(worker.count)]")
}
}
queue3.async {
range.forEach { _ in
worker.work()
print("πŸ”΄ Done [\(worker.count)]")
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
// Always return the current value from the work item to get the correct value.
import PlaygroundSupport
import Foundation
class Worker {
private let workerQueue = DispatchQueue(label: "com.acme.worker")
private let serialQueue = DispatchQueue(label: "com.acme.serial")
private var count = 0
func incrementCount() {
serialQueue.sync {
count += 1
}
}
func value() -> Int {
return serialQueue.sync {
count
}
}
func work() -> Int {
var currentCount = 0
let workItem = DispatchWorkItem() { [weak self] in
guard let s = self else { return }
s.incrementCount()
print("πŸ”΅ Work [\(s.value())]")
currentCount = s.value()
}
workerQueue.async(execute: workItem)
workItem.wait()
return currentCount
}
}
let worker = Worker()
let queue1 = DispatchQueue(label: "com.acme.queue1", attributes: .concurrent)
let queue2 = DispatchQueue(label: "com.acme.queue2", attributes: .concurrent)
let queue3 = DispatchQueue(label: "com.acme.queue3", attributes: .concurrent)
let range = 0..<5
queue1.async {
range.forEach { _ in
let count = worker.work()
print("πŸ”΄ Done [\(count)]")
}
}
queue2.async {
range.forEach { _ in
let count = worker.work()
print("πŸ”΄ Done [\(count)]")
}
}
queue3.async {
range.forEach { _ in
let count = worker.work()
print("πŸ”΄ Done [\(count)]")
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
import PlaygroundSupport
import Foundation
class Worker {
private let workerQueue = DispatchQueue(label: "com.acme.worker")
private let serialQueue = DispatchQueue(label: "com.acme.serial")
private var count = 0
func incrementCount() {
serialQueue.sync {
count += 1
}
}
func value() -> Int {
return serialQueue.sync {
count
}
}
func work() {
let workItem = DispatchWorkItem() { [weak self] in
guard let s = self else { return }
s.incrementCount()
print("πŸ”΅ Work [\(s.value())]")
}
workerQueue.async(execute: workItem)
workItem.wait()
}
}
let worker = Worker()
let queue1 = DispatchQueue(label: "com.acme.queue1", attributes: .concurrent)
let queue2 = DispatchQueue(label: "com.acme.queue2", attributes: .concurrent)
let queue3 = DispatchQueue(label: "com.acme.queue3", attributes: .concurrent)
let range = 0..<5
queue1.async {
range.forEach { _ in
worker.work()
print("πŸ”΄ Done [\(worker.value())]")
}
}
queue2.async {
range.forEach { _ in
worker.work()
print("πŸ”΄ Done [\(worker.value())]")
}
}
queue3.async {
range.forEach { _ in
worker.work()
print("πŸ”΄ Done [\(worker.value())]")
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment