Skip to content

Instantly share code, notes, and snippets.

@Nonda95
Created April 15, 2019 07:06
Show Gist options
  • Save Nonda95/4e0978ef9879e74869ced9d7a16ad13e to your computer and use it in GitHub Desktop.
Save Nonda95/4e0978ef9879e74869ced9d7a16ad13e to your computer and use it in GitHub Desktop.
Kotlin Coroutines PoC of Go's singleflight
import kotlinx.coroutines.*
private val deferreds = mutableMapOf<String, Deferred<*>>()
@Suppress("UNCHECKED_CAST")
fun <T> doAsync(key: String, action: suspend () -> T): Deferred<T> {
val deferredResult = deferreds[key]?.takeIf { it.isActive }
?: GlobalScope.async { action() }.also { deferreds[key] = it }
return deferredResult as Deferred<T>
}
fun forget(key: String) {
deferreds[key]?.cancel()
}
import kotlinx.coroutines.*
suspend fun main() = coroutineScope {
val result1 = doAsync("delay") {
delay(500L)
println("Do only once")
1
}
val result2 = doAsync("delay") {
delay(500L)
println("Do only once")
2
}
result1.await()
val result3 = doAsync("delay") {
delay(500L)
println("Do once more")
3
}
println("result1: ${result1.await()}, result2: ${result2.await()}, result3: ${result3.await()}")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment