``` private val topics = mutableMapOf<Strin...
# coroutines
i
Copy code
private val topics = mutableMapOf<String, Publisher>()
    private val lock = Mutex()

    suspend fun method(key: String) {
        lock.withLock { 
            topics.getOrPut(key) { //... }
        }
    }
is lock gives guarantee that other coroutines will see changes in
topics
?
g
Should do the trick, yes. Although, the suggested way would be to transform it into a coroutine or an actor: https://stackoverflow.com/questions/49985933/mutex-the-right-way Can't provide you with the example, never tried it.
i
Yes, I know that actor solves my problem, but then I need to pass completion handler as part of message to actor, and this changes current design.
g
do you mind to share a snippet with actor? I'm doing something similar, but also with locks so far, didn't bother to change..
also, if you have more reads than writes, instead of blocking the whole map,
ConcurrentHashMap
could be a better solution.
i
Currently I do smth like:
Copy code
# thrift async server handler method:
override fun action(data, resultHandler: AsyncMethodCallback<ResultCode>) {
  ~ process(data)
  resultHandler.onComplete(ResultCode.OK)
}
Where
process
shown before So I can create actor, and pass completion call:
{ resultHandler.onComplete(ResultCode.OK) }
as additional field in data
also, if you have more reads than writes, instead of blocking the whole map,
ConcurrentHashMap
could be a better solution.
but it will block whole thread, that's I think can be bad
g
what do you mean ConcurrentHashMap will block the whole thread? With mutex you synchronize on the whole collection. With ConcurrentHashMap (no mutext) you have concurrent reads and mostly concurrent writes. So, the collection will be blocked less often. Unless you have the same r/w ratio, than it's almost the same.
d
He means that using the mutex, he uses the suspension feature, unlike if he used ConcurrentHashMap, which blocks threads.
e
If the only thing you do in lock is put/get to/from map, then using CHM would give you much better performance and scalability in all conceivable scenarios.
1
g
as an exercise, is that how you rewrite this example with actors: https://pl.kotl.in/S1ALD9dXN? Or even somehow combine the actor with another
produce
coroutine instead of
CompletableDeferred<String?>
?
d
A channel for outputs doesn't really make sense. Consider replacing the
CompletableDeferred
with a
Continuation
Doesn't make sense because it would be a completely different style of programming* as you would have to subscribe for when the data becomes available with some callback
So you'd probably end up wrapping the channel with another coroutine system to get the results to the right callbacks