-
Notifications
You must be signed in to change notification settings - Fork 47.2k
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
Deterministic updates #10715
Deterministic updates #10715
Conversation
2d46bad
to
20eb374
Compare
e2ab6b9
to
d47de1e
Compare
Deploy preview ready! Built with commit e2ab6b9 |
Deploy preview ready! Built with commit d0d798e |
9a31c91
to
d0d798e
Compare
d70d52e
to
e3debd7
Compare
props: mixed, | ||
renderExpirationTime: ExpirationTime, | ||
): State { | ||
): State | null { |
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.
Why can this return null
now?
) { | ||
const coalescedTime = insertAfter.expirationTime; | ||
queue.expirationTime = update.expirationTime; | ||
} |
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.
If you expand the if (queue.last === null) {
block to include the else
condition instead of doing an early return, we can reuse this logic for both branches instead of duplicating.
e3debd7
to
1990983
Compare
High priority updates typically require less work to render than low priority ones. It's beneficial to flush those first, in their own batch, before working on more expensive low priority ones. We do this even if a high priority is scheduled after a low priority one.
However, we don't want this reordering of updates to affect the terminal state. State should be deterministic: once all work has been flushed, the final state should be the same regardless of how they were scheduled.
To get both properties, we store updates on the queue in insertion order instead of priority order (always append). Then, when processing the queue, we skip over updates with insufficient priority. Instead of removing updates from the queue right after processing them, we only remove them if there are no unprocessed updates before it in the list.
This means that updates may be processed more than once.
As a bonus, the new implementation is simpler and requires less code.
To avoid conflicts, this works off my expiration times (#10426) and prerendering (#10624) PRs.