-
Notifications
You must be signed in to change notification settings - Fork 4k
Schedule trigger events at the end of the event loop #10018
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
2bfae04 to
865fc55
Compare
865fc55 to
931cd07
Compare
| * the setTimeout is used to ensure the input field value is sent to the server before the button click | ||
| * by putting the the button click in the end of the event loop | ||
| * | ||
| * Returns a promise that is resolved as soon as the timeout was triggered for testing purposes. |
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 fully understand this part -- is it referring to the 0 timeout that will ensure we don't wait to add this to the task queue, or something else?
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.
Are you referring to the entire JS doc or the last part about the promise return? I have updates the doc string slightly, perhaps its clearer now?
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.
Yeah, the rewording is clearer to me, thanks! Added a nit on the english.
|
LGTM I just found some of the description and comments a bit hard to follow and suggested some changes that I think would be clearer. |
07296eb to
43f3a08
Compare
Co-authored-by: Laura Wilby <[email protected]>
43f3a08 to
95d3de3
Compare
Co-authored-by: Laura Wilby <[email protected]>
This is a small change to the setTriggerValueAtEndOfEventLoop docstring based on discussion [in this PR](#10018 (comment)). ## Describe your changes ## GitHub Issue Link (if applicable) ## Testing Plan Docstring only, no tests needed. --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
## Describe your changes Put trigger-caused actions at the end of the event loop to let other events that change & sync input data come first if they happen at the same time. ## GitHub Issue Link (if applicable) Closes streamlit#10007 ## Testing Plan - Updated existing unit tests because with the timeout they started to fail - Added an e2e test with the logic reported in streamlit#10007. The test fails without the `setTimeout` as it mimics exactly what the user reported. --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
This is a small change to the setTriggerValueAtEndOfEventLoop docstring based on discussion [in this PR](streamlit#10018 (comment)). ## Describe your changes ## GitHub Issue Link (if applicable) ## Testing Plan Docstring only, no tests needed. --- **Contribution License Agreement** By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
Describe your changes
An observed user behavior in Streamlit is to change some widget's input and then directly click on a button to submit the change and see the result in the web app.
When not losing the focus on the input field first, this can sometimes lead to the trigger rerun message being sent to the server before the input's change rerun update. If the trigger button's action accesses the other widget's state, the state is read before the input's change data is processed and the update is only visible upon the next rerun as reported in #10007.
This PR wraps the
setTriggerValuefunctions in asetTimeout(setTriggerValueLogic, 0)call. When the input's value change is in JS' event loop, e.g. via anonBlurevent, and the trigger value is on the event loop, e.g. via a button'sonClickevent, this wrapper will put the trigger value at the end of the current event loop (without any measurable delay due to timeout0). This assumes that we usually want to process other rerun data first and the trigger value as a follow-up action of that information. Even if this assumption is not true, right now without the PR the order is random and with this we put some more deterministic behavior around the messages which should not make any situation worse.Note that the e2e test would also fail if we use the normal execution flow and not a callback on the button. Also, the e2e test is able to trigger the bug always, whereas manually I was only able to trigger it when loading the page in Chrome's mobile device emulator as reported by the user in
#10007. My assumption is that playwright and the mobile touch on the button are fast enough to schedule the event, whereas a mouse click loses focus on the text area first before triggering the click which puts the text area's onBlur event in front of the trigger event in JS' event loop.
I believe this behavior changed in recent versions where we refactored the components to functional ones using some custom hooks to sync the new value internally and committing to the server. My assumption is that this increased the likelihood of events being scheduled later in the event loop.
GitHub Issue Link (if applicable)
Closes #10007
Testing Plan
setTimeoutas it mimics exactly what the user reported.Contribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.