@@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
1212import kotlinx.coroutines.flow.StateFlow
1313import kotlinx.coroutines.isActive
1414import kotlinx.coroutines.launch
15+ import kotlinx.coroutines.yield
1516
1617/* *
1718 * Launches the [workflow] in a new coroutine in [scope] and returns a [StateFlow] of its
@@ -170,15 +171,15 @@ public fun <PropsT, OutputT, RenderingT> renderWorkflowIn(
170171 }
171172
172173 scope.launch {
173- while (isActive) {
174+ outer@ while (isActive) {
174175 // It might look weird to start by processing an action before getting the rendering below,
175176 // but remember the first render pass already occurred above, before this coroutine was even
176177 // launched.
177178 var actionResult: ActionProcessingResult = runner.processAction()
178179
179180 if (shouldShortCircuitForUnchangedState(actionResult)) {
180181 sendOutput(actionResult, onOutput)
181- continue
182+ continue @outer
182183 }
183184
184185 // After resuming from runner.processAction() our coroutine could now be cancelled, check so
@@ -189,15 +190,22 @@ public fun <PropsT, OutputT, RenderingT> renderWorkflowIn(
189190 var nextRenderAndSnapshot: RenderingAndSnapshot <RenderingT > = runner.nextRendering()
190191
191192 if (runtimeConfig.contains(CONFLATE_STALE_RENDERINGS )) {
192- while (isActive && actionResult is ActionApplied <* > && actionResult.output == null ) {
193+ conflate@ while (isActive && actionResult is ActionApplied <* > && actionResult.output == null ) {
194+ // We start by yielding, because if we are on an Unconfined dispatcher, we want to give
195+ // other signals (like Workers listening to the same result) a chance to get dispatched
196+ // and queue their actions.
197+ yield ()
193198 // We may have more actions we can process, this rendering could be stale.
194199 actionResult = runner.processAction(waitForAnAction = false )
195200
196201 // If no actions processed, then no new rendering needed. Pass on to UI.
197- if (actionResult == ActionsExhausted ) break
202+ if (actionResult == ActionsExhausted ) break @conflate
198203
199204 // Skip rendering if we had unchanged state, keep draining actions.
200- if (shouldShortCircuitForUnchangedState(actionResult)) continue
205+ if (shouldShortCircuitForUnchangedState(actionResult)) {
206+ sendOutput(actionResult, onOutput)
207+ continue @outer
208+ }
201209
202210 // Make sure the runtime has not been cancelled from runner.processAction()
203211 if (! isActive) return @launch
0 commit comments