Skip to content

Instantly share code, notes, and snippets.

@uzzu
Last active December 11, 2018 07:06
Show Gist options
  • Save uzzu/ce45d53c859629f9463070e4bff6c4fb to your computer and use it in GitHub Desktop.
Save uzzu/ce45d53c859629f9463070e4bff6c4fb to your computer and use it in GitHub Desktop.
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
interface HotCoroutineScope : CoroutineScope {
val jobMap: MutableMap<String, Job>
fun launchHot(
key: String,
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
println("hot jobs count: ${jobMap.size}\n")
return jobMap.getOrPut(key) {
println("[$key] launch\n")
launch(context, start, block).also {
it.invokeOnCompletion {
println("[$key] completed\n")
jobMap.remove(key)
}
}
}
}
}
class Presenter(
ui: CoroutineDispatcher,
private val io: CoroutineDispatcher
) : HotCoroutineScope {
private val job: Job = Job()
private var callCount = 0
override val coroutineContext: CoroutineContext = job + ui
override val jobMap: MutableMap<String, Job> = mutableMapOf()
fun foo(value: Int) {
launchHot("suspendFun$value") {
runCatching { withContext(io) { suspendFun(value) } }
.onSuccess { render(it) }
.onFailure { render(it) }
}
}
suspend fun suspendFun(value: Int): Int {
println("callCount: ${++callCount}\n")
delay(50)
return value * value
}
fun render(result: Int) {
println("result: $result\n")
}
fun render(e: Throwable) {
println("error: $e\n")
}
}
fun process(value: Int) = runBlocking {
val presenter = Presenter(Dispatchers.Default, Dispatchers.IO)
repeat(50) {
delay(10)
print("call[$it]\n")
presenter.foo(value)
}
print("presenter.jobcount: ${presenter.jobMap.size}\n")
}
process(5)
call[0]
hot jobs count: 0
[suspendFun5] launch
callCount: 1
call[1]
hot jobs count: 1
call[2]
hot jobs count: 1
call[3]
hot jobs count: 1
call[4]
hot jobs count: 1
call[5]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[6]
hot jobs count: 0
[suspendFun5] launch
callCount: 2
call[7]
hot jobs count: 1
call[8]
hot jobs count: 1
call[9]
hot jobs count: 1
call[10]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[11]
hot jobs count: 0
[suspendFun5] launch
callCount: 3
call[12]
hot jobs count: 1
call[13]
hot jobs count: 1
call[14]
hot jobs count: 1
call[15]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[16]
hot jobs count: 0
[suspendFun5] launch
callCount: 4
call[17]
hot jobs count: 1
call[18]
hot jobs count: 1
call[19]
hot jobs count: 1
call[20]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[21]
hot jobs count: 0
[suspendFun5] launch
callCount: 5
call[22]
hot jobs count: 1
call[23]
hot jobs count: 1
call[24]
hot jobs count: 1
call[25]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[26]
hot jobs count: 0
[suspendFun5] launch
callCount: 6
call[27]
hot jobs count: 1
call[28]
hot jobs count: 1
call[29]
hot jobs count: 1
call[30]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[31]
hot jobs count: 0
[suspendFun5] launch
callCount: 7
call[32]
hot jobs count: 1
call[33]
hot jobs count: 1
call[34]
hot jobs count: 1
call[35]
hot jobs count: 1
call[36]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[37]
hot jobs count: 0
[suspendFun5] launch
callCount: 8
call[38]
hot jobs count: 1
call[39]
hot jobs count: 1
call[40]
hot jobs count: 1
call[41]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[42]
hot jobs count: 0
[suspendFun5] launch
callCount: 9
call[43]
hot jobs count: 1
call[44]
hot jobs count: 1
call[45]
hot jobs count: 1
call[46]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[47]
hot jobs count: 0
[suspendFun5] launch
callCount: 10
call[48]
hot jobs count: 1
call[49]
hot jobs count: 1
presenter.jobcount: 1
result: 25
[suspendFun5] completed
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
interface HotCoroutineScope : CoroutineScope {
val jobMap: MutableMap<String, Job>
fun launchHot(
key: String,
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
println("hot jobs count: ${jobMap.size}\n")
return jobMap.getOrPut(key) {
println("[$key] launch\n")
launch(context, start, block).also {
it.invokeOnCompletion {
println("[$key] completed\n")
jobMap.remove(key)
}
}
}
}
}
class Presenter(
ui: CoroutineContext,
private val io: CoroutineDispatcher
) : HotCoroutineScope {
private val job: Job = Job()
private var callCount = 0
override val coroutineContext: CoroutineContext = job + ui
override val jobMap: MutableMap<String, Job> = mutableMapOf()
fun foo(value: Int) {
launchHot("suspendFun$value") {
runCatching { withContext(io) { suspendFun(value) } }
.onSuccess { render(it) }
.onFailure { render(it) }
}
}
suspend fun suspendFun(value: Int): Int {
println("callCount: ${++callCount}\n")
delay(50)
return value * value
}
fun render(result: Int) {
println("result: $result\n")
}
fun render(e: Throwable) {
println("error: $e\n")
}
}
fun process(value: Int) = runBlocking {
val presenter = Presenter(coroutineContext, Dispatchers.IO)
repeat(50) {
delay(10)
print("call[$it]\n")
presenter.foo(value)
}
print("presenter.jobcount: ${presenter.jobMap.size}\n")
}
process(5)
call[0]
hot jobs count: 0
[suspendFun5] launch
callCount: 1
call[1]
hot jobs count: 1
call[2]
hot jobs count: 1
call[3]
hot jobs count: 1
call[4]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[5]
hot jobs count: 0
[suspendFun5] launch
callCount: 2
call[6]
hot jobs count: 1
call[7]
hot jobs count: 1
call[8]
hot jobs count: 1
call[9]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[10]
hot jobs count: 0
[suspendFun5] launch
callCount: 3
call[11]
hot jobs count: 1
call[12]
hot jobs count: 1
call[13]
hot jobs count: 1
call[14]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[15]
hot jobs count: 0
[suspendFun5] launch
callCount: 4
call[16]
hot jobs count: 1
call[17]
hot jobs count: 1
call[18]
hot jobs count: 1
call[19]
hot jobs count: 1
call[20]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[21]
hot jobs count: 0
[suspendFun5] launch
callCount: 5
call[22]
hot jobs count: 1
call[23]
hot jobs count: 1
call[24]
hot jobs count: 1
call[25]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[26]
hot jobs count: 0
[suspendFun5] launch
callCount: 6
call[27]
hot jobs count: 1
call[28]
hot jobs count: 1
call[29]
hot jobs count: 1
call[30]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[31]
hot jobs count: 0
[suspendFun5] launch
callCount: 7
call[32]
hot jobs count: 1
call[33]
hot jobs count: 1
call[34]
hot jobs count: 1
call[35]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[36]
hot jobs count: 0
[suspendFun5] launch
callCount: 8
call[37]
hot jobs count: 1
call[38]
hot jobs count: 1
call[39]
hot jobs count: 1
call[40]
hot jobs count: 1
call[41]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[42]
hot jobs count: 0
[suspendFun5] launch
callCount: 9
call[43]
hot jobs count: 1
call[44]
hot jobs count: 1
call[45]
hot jobs count: 1
call[46]
hot jobs count: 1
result: 25
[suspendFun5] completed
call[47]
hot jobs count: 0
[suspendFun5] launch
callCount: 10
call[48]
hot jobs count: 1
call[49]
hot jobs count: 1
presenter.jobcount: 1
result: 25
[suspendFun5] completed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment