https://kotlinlang.org logo
#compose
Title
# compose
z

Zach Klippenstein (he/him) [MOD]

06/08/2020, 9:52 PM
I don’t expect polished documentation at this point, but are there any code comments or anything that would helpful to read to learn about the composition “commit lifecycle” in more detail? E.g.
launchInComposition
launches the coroutine on commit, and cancels it on dispose, but it’s not clear if there’s any case in which a coroutine could be launched again in the same point in the composition, after being cancelled. Or whether
onDispose
is called if the composition fails before
onCommit
gets invoked.
@Adam Powell mentions avoiding having to “try to rollback” when the composition fails, but if
onCommit
will only be called once for a given point in the composition, then as long as
onDispose
is called on composition failure it seems like rolling back would be fairly trivial. I feel like I’m missing some piece of the puzzle here. Maybe
onCommit
can be called multiple times? https://kotlinlang.slack.com/archives/CJLTWPH7S/p1591565761398100?thread_ts=1591558024.394400&cid=CJLTWPH7S
a

Adam Powell

06/08/2020, 11:21 PM
Good callout, we've been talking about improving a bunch of the docs in this area soon 🙂
🙏🏼 5
onDispose
is not called on composition failure, it is called to dispose the result of a previous successful composition
👍 1
launchInComposition
is a sort of task that exists at its position in the composable function; just like a UI element it runs when it becomes present and is cancelled if it leaves the composition before finishing. It does not run again unless you provide it with comparison values that change from one recomposition to another, in which case it will cancel the currently running task block before launching the new one.
we've considered renaming it to
Task
or similar to reinforce this noun-entity behavior of presence in the composition (and joked about calling it
AsyncTask
in particular)
😅 6
c

Chuck Jazdzewski [G]

06/08/2020, 11:59 PM
To clarify some underlying semantics not covered by Adam,
onCommit
's lambda is only called once the composition succeeds that contains the
onCommit
.
onDispose
is only called if
onCommit
is called and only after composition succeeds that removes the
onCommit
from the composition. Calling the
onCommit
and
onDispose
lambdas is the last step of composition after it has committed to using the results of composition. The quote from Adam above was regarding side-effects in an
@Composable
function outside of
onCommit
. For example, if you launched a coroutine directly using the main dispatcher in the
@Composable
function, this might start a job that is unnecessary and need to be cancelled. However, we currently do not have an API to inform a
@Composable
function that its results were discarded. We, therefore, recommend all effects be contained in an
onCommit
or similar effect such as
launchInComposition
which uses
onCommit
internally (well, actually, it uses
CompositionLifecycleObserver
which is what
onCommit
uses too, but that is an implementation detail).
💯 1
🙏 1
1
v

Vinay Gaba

06/09/2020, 12:06 AM
Just to be clear I understood this correctly, the recommendation is to wrap mutations/side effects inside the onCommit block? So something like this?
Copy code
val count by state {0}

onCommit {
 count = count + 1
}
I am almost certain I misunderstood the discussion in the previous thread that Zach linked 😅
t

Tash

06/09/2020, 12:11 AM
This discussion is already offering a lot more clarity than the existing code docs so thank y’all. Also curious how
onPreCommit
comes into play here, as I see it is used in some internal Compose components.
1
😅 1
z

Zach Klippenstein (he/him) [MOD]

06/09/2020, 2:55 AM
Thanks a lot for the explanation, Chuck & Adam! Good to know exactly how initializing any kind of resource in a Composable function outside of commit is a potential leak. I am also curious about how
onPreCommit
fits into all of this, and a little curious in what scenario, without multi-threading, a composition could fail, but that’s not as interesting as knowing how compose behaves when it happens, so thanks again.
1
4 Views