Skip to content

Commit ab23b7b

Browse files
Use WorkStealingDispatcher in runtime, behind a flag.
1 parent 484d9c5 commit ab23b7b

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

workflow-core/src/commonMain/kotlin/com/squareup/workflow1/RuntimeConfig.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ public enum class RuntimeConfigOptions {
7474
// */
7575
// @WorkflowExperimentalRuntime
7676
// DRAIN_EXCLUSIVE_ACTIONS,
77+
78+
/**
79+
* Wrap the dispatcher passed to the runtime with a special dispatcher that can be advanced
80+
* explicitly, to allow any tasks scheduled by the workflow runtime to run before certain phases.
81+
*/
82+
@WorkflowExperimentalRuntime
83+
WORK_STEALING_DISPATCHER,
7784
;
7885

7986
public companion object {
@@ -136,6 +143,7 @@ public enum class RuntimeConfigOptions {
136143
STABLE_EVENT_HANDLERS,
137144
)
138145
),
146+
139147
// RENDER_ONLY_CONFLATE_PARTIAL_DEA(
140148
// setOf(
141149
// RENDER_ONLY_WHEN_STATE_CHANGES,
@@ -161,6 +169,7 @@ public enum class RuntimeConfigOptions {
161169
// DRAIN_EXCLUSIVE_ACTIONS,
162170
// )
163171
// ),
172+
ALL(RuntimeConfigOptions.entries.toSet())
164173
}
165174
}
166175
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.squareup.workflow1.RuntimeConfigOptions.CONFLATE_STALE_RENDERINGS
44
import com.squareup.workflow1.RuntimeConfigOptions.RENDER_ONLY_WHEN_STATE_CHANGES
55
import com.squareup.workflow1.WorkflowInterceptor.RenderPassSkipped
66
import com.squareup.workflow1.WorkflowInterceptor.RenderPassesComplete
7+
import com.squareup.workflow1.internal.WorkStealingDispatcher
78
import com.squareup.workflow1.internal.WorkflowRunner
89
import com.squareup.workflow1.internal.chained
910
import kotlinx.coroutines.CancellationException
@@ -14,6 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
1415
import kotlinx.coroutines.flow.StateFlow
1516
import kotlinx.coroutines.isActive
1617
import kotlinx.coroutines.launch
18+
import kotlinx.coroutines.plus
1719

1820
/**
1921
* Launches the [workflow] in a new coroutine in [scope] and returns a [StateFlow] of its
@@ -117,6 +119,13 @@ public fun <PropsT, OutputT, RenderingT> renderWorkflowIn(
117119
): StateFlow<RenderingAndSnapshot<RenderingT>> {
118120
val chainedInterceptor = interceptors.chained()
119121

122+
val dispatcher = if (RuntimeConfigOptions.WORK_STEALING_DISPATCHER in runtimeConfig) {
123+
WorkStealingDispatcher.wrapDispatcherFrom(scope.coroutineContext)
124+
} else null
125+
126+
@Suppress("NAME_SHADOWING")
127+
val scope = dispatcher?.let { scope + dispatcher } ?: scope
128+
120129
val runner = WorkflowRunner(
121130
scope,
122131
workflow,
@@ -202,6 +211,9 @@ public fun <PropsT, OutputT, RenderingT> renderWorkflowIn(
202211
conflationHasChangedState = conflationHasChangedState || actionResult.stateChanged
203212
// We may have more actions we can process, this rendering could be stale.
204213
// This will check for any actions that are immediately available and apply them.
214+
// We advance the dispatcher first to allow any coroutines that were launched by the last
215+
// render pass to start up and potentially enqueue actions.
216+
dispatcher?.advanceUntilIdle()
205217
actionResult = runner.applyNextAvailableTreeAction()
206218

207219
// If no actions processed, then no new rendering needed. Pass on to UI.

workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/RenderWorkflowInTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.squareup.workflow1.RuntimeConfigOptions.Companion.RuntimeOptions
66
import com.squareup.workflow1.RuntimeConfigOptions.Companion.RuntimeOptions.DEFAULT
77
import com.squareup.workflow1.RuntimeConfigOptions.PARTIAL_TREE_RENDERING
88
import com.squareup.workflow1.RuntimeConfigOptions.RENDER_ONLY_WHEN_STATE_CHANGES
9+
import com.squareup.workflow1.RuntimeConfigOptions.WORK_STEALING_DISPATCHER
910
import com.squareup.workflow1.WorkflowInterceptor.RenderPassSkipped
1011
import com.squareup.workflow1.WorkflowInterceptor.RenderPassesComplete
1112
import com.squareup.workflow1.WorkflowInterceptor.RuntimeLoopOutcome
@@ -1494,7 +1495,9 @@ class RenderWorkflowInTest(
14941495

14951496
@Test
14961497
fun for_conflate_we_do_not_conflate_stacked_actions_into_one_rendering_if_output() {
1497-
if (runtimeConfig.contains(CONFLATE_STALE_RENDERINGS)) {
1498+
if (CONFLATE_STALE_RENDERINGS in runtimeConfig &&
1499+
WORK_STEALING_DISPATCHER !in runtimeConfig
1500+
) {
14981501
runTest(dispatcherUsed) {
14991502
check(runtimeConfig.contains(CONFLATE_STALE_RENDERINGS))
15001503

0 commit comments

Comments
 (0)