https://kotlinlang.org logo
#coroutines
Title
# coroutines
d

dave08

11/11/2018, 2:02 PM
Apart from using a Channel/Actor, is there any easy way to implement an
ConcurrentHashMap
with coroutines that suspends the current Coroutine instead of blocking the thread? Sometimes retrieval of missing values can take time...
g

gildor

11/11/2018, 2:33 PM
what you don’t want to use Actor/Channel? Which is good solution for this problem (especially if you wrap them to some abstraction, like custom Map interface with suspend methods) Any attempt to avoid using channels in this case as result will be just simplified implementation of channels
d

dave08

11/11/2018, 2:36 PM
It's basically being used as caches in Ktor, so it's a pity to instantiate tons of objects per request to the cache... but I still want Ktor to continue serving requests of things that are already in the cache.
l

littlelightcz

11/11/2018, 6:47 PM
Well, if you would access this map from within of
withContext(IO) {...}
, then I think you will get the behaviour you're describing. With that you could write an extension suspending function for
Map
in general (or
ConcurrentHashMap
specifically), which could do the get operation in this fashion automatically.
So perhaps something like this? https://pl.kotl.in/HJ4b5xIp7
d

dave08

11/11/2018, 8:47 PM
I was thinking more along the lines of using a Mutex with a regular MutableMap.. I'm not sure of it's any better though.
g

gildor

11/12/2018, 12:54 AM
I don't think that Mufex is somehow better
To be honest I never see good usages for coroutines Mutex, usually code with channel is more simple and safe
But use MutableMap managed by actor is definitely make sense
t

tateisu

11/12/2018, 2:20 AM
Using coroutine for implementing concurrent containers is toppling overhead. Because Coroutine abstracts the implementation of dispatcher, you can not estimate the processing cost of the Concurrent container. For example, the current implementation of Dispatchers.IO is a LimitingDispatcher that uses ConcurrentLinkedQueue. In this way you can not escape from "java.util.concurrent. *" Just by adding extra overhead.
d

dave08

11/12/2018, 2:43 AM
That's why I thought it might be nice to have some kind of Coroutines primitive for this. It would seem to me that all the object allocations for each get/set call in an actor, would overweigh the benefits....
t

tateisu

11/12/2018, 3:05 AM
Coroutine itself is just continuation. also dispatcher is just codes to use continuation. even if you move some codes to built-in, it does not make fast your code. there is no magic.
d

dave08

11/12/2018, 7:31 AM
Not blazing fast, but suspendable and not wasteful 🙂. The use case is a cache, which in itself takes up lots of memory, to add all the object instantiation and GCing, might not be a good idea. On the other hand, the regular implementation blocks instead of suspending meaning that less requests can be dealt with while loading elements into the cache, even though there might be what these requests need already there...
d

Dico

11/12/2018, 11:50 AM
Java's GC is blazing fast nowadays. It really is. C# is far behind in this regard. Stop assuming that object allocation will slow stuff down. Short allocations might be placed on the stack, even.
Do some testing is what I'm saying.
2 Views