-
Notifications
You must be signed in to change notification settings - Fork 106
Update CSR to yield() and update tests #1294
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
workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/RenderWorkflow.kt
Outdated
Show resolved
Hide resolved
9f218b2
to
dbd02dc
Compare
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.
So this is great in that it now actually runs the tests the way we run the code in Register. However, it removes test coverage for normal dispatchers. Are we officially dropping support for non-immediate dispatchers? I thought we had some headless ones in Register, so we probably can't do that. It looks like we already have some kind of parameterized testing infra, can we use that to test on both types of dispatchers?
workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/RenderWorkflow.kt
Show resolved
Hide resolved
|
||
// Skip rendering if we had unchanged state, keep draining actions. | ||
if (shouldShortCircuitForUnchangedState(actionResult)) continue | ||
if (shouldShortCircuitForUnchangedState(actionResult)) { | ||
// Emit the Output |
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.
Nit: This comment is pretty redundant, "emit" is just another word for "send" and that's literally the function name.
|
||
// Skip rendering if we had unchanged state, keep draining actions. | ||
if (shouldShortCircuitForUnchangedState(actionResult)) continue | ||
if (shouldShortCircuitForUnchangedState(actionResult)) { | ||
// Emit the Output |
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.
Nit: This comment is pretty redundant, "emit" is just another word for "send" and that's literally the function name.
|
||
// Skip rendering if we had unchanged state, keep draining actions. | ||
if (shouldShortCircuitForUnchangedState(actionResult)) continue | ||
if (shouldShortCircuitForUnchangedState(actionResult)) { | ||
// Emit the Output |
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.
Nit: This comment is pretty redundant, "emit" is just another word for "send" and that's literally the function name.
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.
Was this some kind of inception?
.... Was this some kind of inception?
..... Was this some kind of inception?
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.
Wtf is going on lol 🫥
} | ||
val collectionJob = launch(UnconfinedTestDispatcher(testScheduler)) { |
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.
Yay for consistency within the test!
The parameterized testing is my own hand-rolled one here due to However, i don't think it would be that simple as the test shape will have to change slightly for a I think your point that "We should test with non-immediate dispatchers" is a good one. Update: Nevermind, I made it work pretty straightforwardly and now test with both types of dispatchers. |
dbd02dc
to
934826b
Compare
UnconfinedTestDispatcher(), | ||
myStandardTestDispatcher |
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.
Sweet!
As I was testing
DRAIN_EXCLUSIVE_ACTIONS
and ensuring that our tests would mirror the way that runtime is usually run (that is, withDispatchers.Main.immediate
- which is an unconfined dispatcher), I realized that we should always be testing withUnconfinedTestDispatcher
in the runtime in order to accurately represent that behavior vis-a-vis these optimizations.That testing change caused me to recognize that if we do not
yield()
before processing extra actions then depending on where the coroutines for processing the updated signals are dispatched, they may not be able to actually process them and send their actions to the sink. (like multiple Workers listening to the same signal).So here we add
yield()
before processing extra actions.There was also a bug where we did not output if we were short-circuiting after an action processed as part of CSR. I fixed this bug and updated the test to ensure it was tested.
I also updated
RenderWorkflowInTest
andWorkflowLifecycleTests
tests to use theUnconfinedTestDispatcher
. There was a confusing@Ignore
d test there that I updated the kdoc on to show why it was ignored.UPDATE: I made the dispatcher one of the parameters for the test and use both
UnconfinedTestDispatcher
andStandardTestDispatcher
.More discussion of this and alternatives: https://square.slack.com/archives/C07UHTZKAPJ/p1744896778454249