-
Notifications
You must be signed in to change notification settings - Fork 108
Use WorkStealingDispatcher in runtime, behind a flag. #1365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
So if this works, use it instead of adding the new Compose dependency? |
4df1469
to
b71978b
Compare
65a8c7f
to
c150bc0
Compare
5adab40
to
b81c18d
Compare
9c0f379
to
26aab12
Compare
b81c18d
to
484d9c5
Compare
a2fe965
to
ab23b7b
Compare
e06b394
to
20e7b6b
Compare
f6e81e9
to
468cef1
Compare
I would still like to get away from Unconfined if there's an opportunity to do so, but if this lets us move faster without shaving that yak, then awesome. |
Changed to draft while I write tests. |
c652b31
to
2547ad1
Compare
20e7b6b
to
e56709d
Compare
2547ad1
to
68c7b69
Compare
@@ -161,6 +169,8 @@ public enum class RuntimeConfigOptions { | |||
// DRAIN_EXCLUSIVE_ACTIONS, | |||
// ) | |||
// ), | |||
|
|||
ALL(RuntimeConfigOptions.entries.toSet()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems to me like it would be a good idea to have a config that turns on all the flags (for testing, but also for green-field uses of the runtime), but if you'd rather I add explicit configs for this new flag I can do that too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment indicating the difference in intention between this and other enum entries that might happen to also contain all entries when they're introduced.
@@ -1494,7 +1501,9 @@ class RenderWorkflowInTest( | |||
|
|||
@Test | |||
fun for_conflate_we_do_not_conflate_stacked_actions_into_one_rendering_if_output() { | |||
if (runtimeConfig.contains(CONFLATE_STALE_RENDERINGS)) { | |||
if (CONFLATE_STALE_RENDERINGS in runtimeConfig && | |||
WORK_STEALING_DISPATCHER !in runtimeConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This tested behavior intentionally changes with WSD on.
I added a single test for the new ordering behavior. I don't know if we need more than that since |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize the latest version of it is not merged yet - but where I would really like to test this is with the tests in AndroidDispatchersRenderWorkflowInTest
workflow-runtime-android/src/androidTest/java/com/squareup/workflow1/android/AndroidDispatchersRenderWorkflowInTest.kt
Currently in the branch from this PR - #1355
We could merge your WSD and then I could rebase and test it with that I guess?
7568824
to
c660617
Compare
446b1d8
to
9cb6cfe
Compare
68c7b69
to
13b4104
Compare
// We advance the dispatcher first to allow any coroutines that were launched by the last | ||
// render pass to start up and potentially enqueue actions. | ||
dispatcher?.let { | ||
workflowTracer.trace("AdvancingWorkflowDispatcher") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@steve-the-edwards I just added this. I figure since this is intended to improve performance, might as well add a trace section to measure the new work preemptively.
13b4104
to
96b655a
Compare
9cb6cfe
to
1be3f23
Compare
96b655a
to
095c5a1
Compare
1be3f23
to
cab0e63
Compare
095c5a1
to
d6512f6
Compare
cab0e63
to
a158414
Compare
Ownership ended with @zach-klippenstein, @steve-the-edwards is this PR's owner now. |
1f49159
to
94d3855
Compare
# Conflicts: # workflow-core/src/commonMain/kotlin/com/squareup/workflow1/RuntimeConfig.kt # workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/RenderWorkflow.kt # workflow-runtime/src/commonTest/kotlin/com/squareup/workflow1/RenderWorkflowInTest.kt
94d3855
to
28db854
Compare
@@ -239,7 +239,7 @@ jobs: | |||
uses: mikepenz/action-junit-report@5f47764eec0e1c1f19f40c8e60a5ba47e47015c5 # v4 | |||
if: always() # always run even if the previous step fails | |||
with: | |||
report_paths: '**/build/test-results/test/TEST-*.xml' | |||
report_paths: '**/build/test-results/jvmTest/TEST-*.xml' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just a bug with the reporting paths that I found while looking at this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is report_paths
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what files it tries to pick up test results from to show in the PR directly. (this was just not working before).
- name: Check with Gradle | ||
uses: ./.github/actions/gradle-task | ||
with: | ||
task: jvmTest --continue -Pworkflow.runtime=all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't test the work stealing dispatcher combinations separately, just adding the 'all' config here for the jvm tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which should be fine b/c we plan to ship that way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'eventually', yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but good point that we should make sure each combination we roll out with has been tested here.
@@ -578,7 +599,7 @@ jobs: | |||
### <start-connected-check-shards> | |||
shardNum: [ 1, 2, 3 ] | |||
### <end-connected-check-shards> | |||
runtime: [ conflate, stateChange, drainExclusive, conflate-stateChange, partial, conflate-partial, stable, conflate-drainExclusive, stateChange-drainExclusive, partial-drainExclusive, conflate-partial-drainExclusive ] | |||
runtime: [ conflate, stateChange, drainExclusive, conflate-stateChange, partial, conflate-partial, stable, conflate-drainExclusive, stateChange-drainExclusive, partial-drainExclusive, conflate-partial-drainExclusive, all ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add 'all' the runtime test shard.
* Note that this is *not effective* when using an immediate or unconfined dispatcher as the | ||
* handling of an action happens synchronously after the coroutine sending it into the sink | ||
* is resumed. This means it never dispatches multiple coroutines that send actions into the sink | ||
* before handling the first, so there is never multiple actions to apply! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added notes here about how CSR and DEA won't work with an immediate or unconfined dispatcher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But WORK_STEALING_DISPATCHER
fixes that, right? If so should say so. If not, what's our actual plan? Seems like we should suggest to the reader whatever it is that we're planning to do in POS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it does not actually fix that. We thought it might until we realized that immediate dispatchers prevent the dispatch of the coroutines for the other actions from happening, so there is nothing to drain after processing just the first action.
The way to fix that would be to use a non immediate dispatcher - e.g. Dispatchers.Main
- along with a frame clock listener that explicitly calls advanceUntilIdle()
for each frame so that we can maintain the guarantee of stably updating the runtime each frame.
I implemented that and tested it here with these tests, but in discussion with @zach-klippenstein we decided that it was not helpful.
- If you are using Compose, then you should use
AndroidUiDispatcher.Main
for this, otherwise the timing of the two frame callbacks might not be right. - If you are not using Compose, we don't really know this and we are OK with just not being able to use CSR or DEA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated it to say this:
* Note further that [WORK_STEALING_DISPATCHER] does not fix this for immediate dispatchers. In
* order to use this optimization, a non-immediate dispatcher must be used. If using a non-
* immediate dispatcher, we recommend that you ensure that the Workflow runtime completes all
* known updates before the next 'frame.' This can be done using a dispatcher that is integrated
* with the frame clock on your platform. E.g., on Android we recommend using Compose UI's
* `AndroidUiDispatcher.Main` in order to access these optimizations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes me think we should just drop CSR then, since it's already pretty redundant with what's built into ComposeView
et al.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought so at first too, but if the view runner work is not cancellable it does save view runner work by producing fewer renderings when they are stale.
@@ -239,7 +239,7 @@ jobs: | |||
uses: mikepenz/action-junit-report@5f47764eec0e1c1f19f40c8e60a5ba47e47015c5 # v4 | |||
if: always() # always run even if the previous step fails | |||
with: | |||
report_paths: '**/build/test-results/test/TEST-*.xml' | |||
report_paths: '**/build/test-results/jvmTest/TEST-*.xml' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is report_paths
?
- name: Check with Gradle | ||
uses: ./.github/actions/gradle-task | ||
with: | ||
task: jvmTest --continue -Pworkflow.runtime=all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which should be fine b/c we plan to ship that way?
* Note that this is *not effective* when using an immediate or unconfined dispatcher as the | ||
* handling of an action happens synchronously after the coroutine sending it into the sink | ||
* is resumed. This means it never dispatches multiple coroutines that send actions into the sink | ||
* before handling the first, so there is never multiple actions to apply! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But WORK_STEALING_DISPATCHER
fixes that, right? If so should say so. If not, what's our actual plan? Seems like we should suggest to the reader whatever it is that we're planning to do in POS.
@@ -98,69 +115,349 @@ public enum class RuntimeConfigOptions { | |||
enum class RuntimeOptions( | |||
val runtimeConfig: RuntimeConfig | |||
) { | |||
DEFAULT(RENDER_PER_ACTION), | |||
NONE(RENDER_PER_ACTION), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holy combinatorial explosion.
28db854
to
d9bbcff
Compare
Installs the
WorkStealingDispatcher
introduced in #1364 into the workflow runtime behind a new runtime flag.