ursus
05/13/2021, 3:51 AMsuspend fun send(someId) {
val currentState = db.getState(someId)
if (currentState == null) error("Unknown id")
if (currentState == Sent) return // idempotent
if (currentState == Sending) .. mutex?
try {
db.setState(Sending, someId)
api.send(..)
db.setState(Sent, someId)
} catch (ex) {
db.setState(Idle, someId)
}
}
This is very common pattern in apps I make.
What would the idiomatic way to make this code thread/coroutine safe?
Obviously, if same id ist being sent concurrently multiple times, state might get smashed
Is it okay to use Mutex around the whole function? Granted, only same ids needs to be serialized -- should I then have a Map<SomeId, Mutex>? Is there maybe some conditional Mutex?
Or maybe not mutex at all, and use some sort of concurrent counter as not to revert to Idle when other coroutine is Sending etc?
Or some Channel magic I dont know?ephemient
05/13/2021, 5:44 AMursus
05/13/2021, 6:01 PMephemient
05/13/2021, 8:02 PMval mutexes = Array(Runtime.getRuntime().availableProcessors()) { Mutex() }
mutexes[Math.floorMod(someId.hashCode(), mutexes.size)].withLock { ... }
ursus
05/13/2021, 8:21 PMephemient
05/13/2021, 8:31 PMursus
05/13/2021, 10:03 PM