Home IOS Development ios – Tips on how to use actors to permit parallel reads however block concurrent reads and writes to a useful resource in Swift?

ios – Tips on how to use actors to permit parallel reads however block concurrent reads and writes to a useful resource in Swift?

0
ios – Tips on how to use actors to permit parallel reads however block concurrent reads and writes to a useful resource in Swift?

[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]

LEAVE A REPLY

Please enter your comment!
Please enter your name here