[ad_1]
So I’ve this code utilizing concurrent dispatch queue and barrier flag to assist parallel reads however block reads/writes when writing:
struct SafeDict<Ingredient> {
non-public var dict = [String: Element]()
non-public var queue = DispatchQueue(label: "WriteQueue", attributes: .concurrent)
func get(_ key: String) -> Ingredient? {
queue.sync { return dict[key] }
}
mutating func set(_ key: String, worth: Ingredient) {
queue.sync(flags: .barrier) { dict[key] = worth }
}
}
var safeDict = SafeDict<Int>()
for i in 1...4 {
DispatchQueue.international().async {
change i {
case 1:
safeDict.get("one")
case 2:
safeDict.set("one", worth: 1) // Waits for get (good)
case 3:
safeDict.get("one") // Runs after set in parallel
case 4:
safeDict.get("two") // Runs after set in parallel
default:
print("performed")
}
}
}
However since actor features are async, parallel reads will wait on one another. How can this be averted cleanly?
One various I can consider is to not use an actor and as an alternative have 2 async strategies (get set). And get will await a set job if not nil. However that appears too tedious.
actor SafeDictActor<Ingredient> {
non-public var dict = [String: Element]()
func get(_ key: String) -> Ingredient? { dict[key] }
func set(_ key: String, worth: Ingredient) { dict[key] = worth }
}
let safeDictActor = SafeDictActor<Int>()
for i in 1...4 {
Job {
change i {
case 1:
await safeDictActor.get("one")
case 2:
await safeDictActor.set("one", worth: 1) // Waits for get (good)
case 3:
await safeDictActor.get("one") // waits for set (good)
case 4:
await safeDictActor.get("two") // waits for earlier get (unhealthy)
default:
print("performed")
}
}
}
[ad_2]