in hot-reload-core/src/main/kotlin/org/jetbrains/compose/reload/core/Task.kt [152:221]
fun start() {
state.update { currentState ->
when (currentState) {
is State.Idle -> State.Running(emptyList())
else -> error("Unexpected state: $currentState")
}
}
suspend {
/* Starting the task */
val result = Try { action() }
/* A failure will cause the entire task graph to stop */
if (result.isFailure()) {
val asyncTraces = coroutineContext[AsyncTraces]
if (asyncTraces != null) {
result.exception.addSuppressed(AsyncTracesThrowable(asyncTraces))
}
stop(result.exception)
}
/* Finishing: Waiting for all children */
while (true) {
val currentState: State<T> = state.get()
val children = when (currentState) {
is State.Running -> currentState.children
is State.Stopping -> currentState.children
is State.Finished<T>, is State.Idle -> error("Unexpected state: $state")
}
/* There are some children: Let's await their result */
if (children.isNotEmpty()) {
children.forEach { child ->
child.value.await()
}
/*
Helping: We know that the children are finished, therefore, we can update/maintain the
state right away
*/
state.update { currentState ->
when (currentState) {
is State.Running -> currentState.copy(children = currentState.children - children)
is State.Stopping -> currentState.copy(children = currentState.children - children)
State.Idle, is State.Finished<*> -> currentState
}
}
continue
}
/* All children finished, we can try transitioning into the 'Finished' state */
val finished: State.Finished<T> = when (currentState) {
is State.Running -> State.Finished(result)
is State.Stopping -> State.Finished(currentState.exception.toRight())
else -> error("Unexpected state: $state")
}
if (state.compareAndSet(currentState, finished)) {
value.completeWith(finished.result)
break
}
}
}.createCoroutine(Continuation(reloadMainDispatcher + coroutineContext + this) { result ->
if (result.isFailure) {
logger.error("Exception in task handling", result.exceptionOrNull())
}
}).resume(Unit)
}