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

spand

06/15/2018, 12:49 PM
I need to lookup something by id asynchronously and limit it to one lookup per id. Would something like this be the way to do it?
Copy code
val cache = ConcurrentHashMap<Int, Deferred<String>>()

suspend fun getById(id: Int) : String {
    return cache.computeIfAbsent(id) {
        async { asyncAction(id) }
    }.await()
}

suspend fun asyncAction(id: Int): String = TODO()
d

dave08

06/15/2018, 2:19 PM
Why not an
actor
?
w

withoutclass

06/15/2018, 2:26 PM
Also, why use
async
only to immediately
await
? may as well just use
withContext
d

Daniel Tam

06/15/2018, 3:48 PM
Is
actor
better only because it doesn't block?
ConcurrentHashMap
is less boilerplate imo, and reads are lock free anyway
b

bj0

06/15/2018, 3:50 PM
actor isnt' really different, it only helps organize things conceptually, but it's more than you need for this case
suspend fun getById(id: Int) = withContext(CommonPool) { asyncAction(id) }
all you need
d

Daniel Tam

06/15/2018, 3:53 PM
I don't think that satisfies the initial use case. Also why
withContext
rather than simply running
asyncAction
?
b

bj0

06/15/2018, 4:11 PM
based on his first post I assumed he wanted it done on a background thread, but maybe not. what wouldn't it satisfy?
w

withoutclass

06/15/2018, 4:22 PM
Copy code
val cache = ConcurrentHashMap<Int, String>()

suspend fun getById(id: Int) : String {
    return cache.computeIfAbsent(id) {
        withContext(IO_DISPATCHER) { asyncAction(id) }
    }
}

suspend fun asyncAction(id: Int): String = "Some String"
This is probably closer to what you want
d

Daniel Tam

06/15/2018, 4:35 PM
I mean it wouldn't satisfy the actual thing he wanted to do with the whole
computeIfAbsent
w

withoutclass

06/15/2018, 4:40 PM
looks to me like it will compute the string if it’s missing to me, so either I fundamentally misunderstand compute if absent or I misunderstand the use case
d

Daniel Tam

06/15/2018, 5:17 PM
sorry, I meant @bj0
b

bj0

06/15/2018, 5:34 PM
I didn't notice the
cache
, was focused on the coroutine stuff and assumed the logic was inside
asyncAction
s

spand

06/16/2018, 11:41 AM
@withoutclass does that compile? The compute call blocks the calling thread and it’s closure is not inline so I avoid that with the async call
The asyncAction is io though so I guess that needs another dispatcher. Thx for that :-)
u

uli

06/16/2018, 5:22 PM
The price is, awaiting the deferred on every cache lookup which should be pretty fast if it is already resolved. I'd say fine if it suits your use case
w

withoutclass

06/17/2018, 5:54 PM
Unsure if it compiles I just did a quick and dirty change
3 Views