Vsevolod Tolstopyatov [JB]
04/27/2018, 3:20 PMasync
and launch
(and other top-level builders as well), define them as extensions on some parent job and provide an easy way to expose such parent job via android integration, new builders etc.
The idea behind this approach is to make ownership of a job (actor, channel, cold stream, w/e) explicit in code, so cancellation will never be an issue.
Then your example will be rewritten as
class MyFragment : Fragment() {
fun loadData() = lifecycle.job().launch(UI) {} // <- job() is extension on lifecycle, won't compile if one tries to write fun loadData() = launch(UI) {}
}
Why do we want to do it if it will require more effort to write concurrent code (and break a lot of existing examples)?
Consider the following snippet:
suspend fun computation() {
val d1 = async {...}
val d2 = async {...}
return merge(d1.await(), d2.await())
}
If d1
will throw an exception, no one will be able to cancel d2
. And if d2
throws another exception, no one will ever observe it!
Though one may argue that it’s a programmer fault, this is how coroutines are usually recommended to be used (actually, it’s a simplified example from our guide).
If async
always should have a receiver, computation
can be written only using some builder, e.g.:
suspend fun computation() = job {
val d1 = async {...} // implicit receiver on `job {}`
val d2 = async {...}
return merge(d1.await(), d2.await())
} // <- here builder will cancel launched tasks if necessary
Now all launched tasks will be properly cancelled/awaited in the end of job {}
and it’s not possible to write computation
without any builder.
To launch jobs from non-suspendable contexts we will provide something like Eternal.async {}
, where Eternal
is object
, so it always will be imported explicitly and code becomes more self-documented: “this job is launched via Eternal, so it can’t be cancelled as part of parent-child hierarchy and either it’s a mistake or it’s a system-wide job”.
Opinions about this idea (note: it’s only a draft, not even prototyped) are welcome