-
Notifications
You must be signed in to change notification settings - Fork 104
1311: Enable applying Multiple Actions on immediate dispatcher for CONFLATE_STALE_RENDERINGS
#1344
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
base: main
Are you sure you want to change the base?
Conversation
key = "Worker3" | ||
) { | ||
action("") { | ||
// Update the rendering in order to show conflation. |
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.
Don't you mean "Update the state"?
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.
Wouldn't the test be more rigorous if you accumulated a bunch of deltas to the state rather than clobbering each time? So at the end you could assert that the rendering = "initial+1+2+3+4"
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.
Yes, that's a much better test!
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.
Done.
|
||
collectionJob.cancel() | ||
|
||
// 2 renderings (initial and then the update.) Not *5* renderings. |
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.
😗 👌
} | ||
|
||
@Test | ||
fun with_conflate_we_conflate_stacked_actions_from_side_effects_into_one_rendering() = |
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 made you decide both tests were necessary? (Don't get me wrong, more is better as far as I'm concerned, just curious.)
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 was early on when i wondered if the Worker machinery was introducing any impedence in resuming to get the actions queued. Its not.
import org.junit.Test | ||
import kotlin.test.assertEquals | ||
|
||
@OptIn(WorkflowExperimentalRuntime::class, ExperimentalCoroutinesApi::class) |
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.
Should you add a test that simulates having an action enqueued via an event handler lambda on a rendering? End to end demonstration of the primary promise we're trying to make to ourselves. Perhaps it should be parameterized to run w/all the config cominbations.
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.
Yup!
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 added these tests (both for deferrable and non deferrable actions). You and @pyricau can double check my logic for asserting on the main thread message.
@@ -348,6 +368,59 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>( | |||
} | |||
} | |||
|
|||
// | |||
// /** |
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.
Commented out b/c not necessary after all? Or is this the thing you have to add to make it actually work?
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.
Not necessary. I just forgot to remove this.
f62f5d7
to
455068b
Compare
A deferrable action is one that can wait a main thread post - such as from an async trigger (Worker). Not a UI action. To allow other actions to queue up, so they can be drained.
455068b
to
4601a04
Compare
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
So this adds the ability to set an action as Ultimately I think we don't want that. we would rather have everything from Workflow's perspective in one main thread message (including teh click action handling). SO I think eventually I'd prefer to make all actions deferrable. but we can go one step at a time? |
First commits adds a failing Android test to demonstrate the problem reported in #1311 .
Second commit fixes this for
CONFLATE_STALE_RENDERINGS
byyield()
ing before applying the first action.The issue with
yield()
in the middle of CSR's inner loop was that it breaks our workflow runtime stabilizing into two main thread messages (yield()
always posts to the Handler). We want to keep the guarantee of each Workflow update in response to an event as happening within 1 main thread message.This solution satisfies that constraint by
yield()
ing before we apply the first action. With these optimizations enabled, whenselect
resumes with a deferrable action ready to be processed, we provide it to the runtime loop as aDeferred
- then weyield()
before applying it. This allows any other possible collectors to go ahead and queue actions. We can then drain them manually withoutselect
in the inner loop for conflate (and later DEA).Note: We add a field for
isDeferrable
on action. Worker actions are by default deferrable. This allows us to opt actions from UI handlers out of this type of optimization.We also add tests on
Main.immediate
that confirm that non-deferrable actions are handled in one main thread message from the callback. Otherwise they are handled in one main thread message from the action application.This also adds new methods for fetching those available actions to apply without
select
(usingtryReceive
) to theWorkflowRunner
andWorkflowNode
as well asWorkflowChildNode
.Fixes #1311