Skip to content

Commit 9b8077c

Browse files
Merge pull request #1294 from square/sedwards/conflate-timeout-1
Update CSR to yield() and update tests
2 parents 2ef97ec + 934826b commit 9b8077c

File tree

3 files changed

+261
-168
lines changed

3 files changed

+261
-168
lines changed

workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/RenderWorkflow.kt

+13-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
1212
import kotlinx.coroutines.flow.StateFlow
1313
import kotlinx.coroutines.isActive
1414
import 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

Comments
 (0)