vaskir
10/01/2018, 12:02 PMAnother example is a server process that spawns several children jobs and needs to supervise their execution, tracking their failures and restarting just those children jobs that had failed.I cannot get my head around how to restart a children (say, an
actor
) from inside a CoroutineExceptionHandler
š What I really need is just restarting strategy a-la Akka.
fun CoroutineScope.worker(ctx: CoroutineContext) = actor<Int>(ctx) {
for (msg in channel) {
println("got $msg")
if (msg == 2) throw Exception("it's $msg and we are failing")
}
}
GlobalScope.launch {
val supervisor = SupervisorJob()
var actor: SendChannel<Int>?
val handler = CoroutineExceptionHandler { _, _ ->
{
actor = worker(coroutineContext + supervisor + handler) // error: handler is not defined
}
}
actor = worker(coroutineContext + supervisor + handler)
for (msg in 1..5)
actor?.send(msg)
}
elizarov
10/01/2018, 12:58 PMelizarov
10/01/2018, 12:58 PMctx
into your worker
function. It is bad style (now). Just define it as extension on CoroutineScope
elizarov
10/01/2018, 12:59 PMworker
from handler like this:
val handler = CoroutineExceptionHandler { context, error ->
CoroutineScope(context).worker()
}
elizarov
10/01/2018, 1:02 PMvaskir
10/01/2018, 6:00 PMelizarov
10/01/2018, 7:01 PMelizarov
10/01/2018, 7:04 PMelizarov
10/01/2018, 7:07 PMval restart = CoroutineExceptionHandler { context, _ -> CoroutineScope(context).worker() }
We can add a āhelperā to make into something like:
val restart = CoroutineRestarter { worker() }
Does it really need further improvement?vaskir
10/01/2018, 7:08 PMelizarov
10/01/2018, 7:09 PMelizarov
10/01/2018, 7:11 PMelizarov
10/01/2018, 7:11 PMvaskir
10/01/2018, 8:11 PMjakiej
10/01/2018, 9:00 PM