Skip to content
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

Fix flow issue #6349 #20255

Merged
merged 1 commit into from
Oct 18, 2024
Merged

Fix flow issue #6349 #20255

merged 1 commit into from
Oct 18, 2024

Conversation

archiecobbs
Copy link
Contributor

Description

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349

Type of change

  • Bugfix
  • Feature

Checklist

  • I have read the contribution guide: https://vaadin.com/docs/latest/guide/contributing/overview/
  • I have added a description following the guideline.
  • The issue is created in the corresponding repository and I have referenced it.
  • I have added tests to ensure my change is effective and works as intended.
  • New and existing tests are passing locally with my change
    • Except JarContentsManagerTest.copyFilesFromJar_doNotUpdateFileIfContentIsTheSame which has nothing to do with this change.
  • I have performed self-review and corrected misspellings.

@mshabarov mshabarov added the Contribution PRs coming from the community or external to the team label Oct 16, 2024
@tepi
Copy link
Contributor

tepi commented Oct 17, 2024

Just to be sure: Is Flow erroneously setting random UI instances to the CurrentInstance value of UI, or is this happening only when the developer is calling UI.setCurrent() themselves within a session access command?

@archiecobbs
Copy link
Contributor Author

archiecobbs commented Oct 17, 2024

Just to be sure: Is Flow erroneously setting random UI instances to the CurrentInstance value of UI, or is this happening only when the developer is calling UI.setCurrent() themselves within a session access command?

HI @tepi ,

The overall problem is that whatever UI (or VaadinRequest or VaadinResponse) happens to be leftover from a previous operation is not removed before the next task in the session's pending access queue is executed.

Note that a "previous operation" could be any of these:

  • The handling of a normal request/response cycle
  • A previous task in the queue (if the affected task is not the first task in the queue)
  • Any other operation which requires a session lock/unlock cycle

As a result, when an enqueued session task invokes UI.getCurrent(), VaadinRequest.getCurrent(), or VaadinResponse.getCurrent(), it can get a "random" value when instead null should have been returned.

So it's not required that the first session task include an explicit call to UI.setCurrent(), it's only required that UI.setCurrent() is called as a side-effect of the previous operation (for example, handling a normal incoming request).

Here is an example of a sequence of events demonstrating one way this could happen:

  • Vaadin HTTP request comes in and is handled by Thread A
  • Thread A locks the session and sets the current UI, VaadinRequest, and VaadinResponse
  • Background thread B wakes up and invokes VaadinSession.access(task)
  • Because the session is already locked by thread A, task is added to the session's pending access queue
  • Thread A finishes handling the request and unlocks the session
  • On session unlock, the pending access queue is processed
  • The task executes in thread A, but:
    • The previous UI, VaadinRequest, and VaadinResponse are still in context
    • Yet those three objects have nothing to do with task

Copy link

Copy link
Contributor

@mshabarov mshabarov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks good to me and safe. Excellent that you added the test, it indeed fails when this patch isn't in place.

Thanks for your contribution 👍

Copy link

Test Results

1 142 files  ± 0  1 142 suites  ±0   1h 30m 37s ⏱️ + 6m 45s
7 465 tests + 1  7 415 ✅ + 1  50 💤 ±0  0 ❌ ±0 
7 831 runs  +51  7 771 ✅ +51  60 💤 ±0  0 ❌ ±0 

Results for commit 1df59e9. ± Comparison against base commit 1937249.

@mshabarov mshabarov merged commit 3bd7a7b into vaadin:main Oct 18, 2024
27 of 28 checks passed
vaadin-bot pushed a commit that referenced this pull request Oct 18, 2024
…20255)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349
vaadin-bot pushed a commit that referenced this pull request Oct 18, 2024
…20255)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349
vaadin-bot pushed a commit that referenced this pull request Oct 18, 2024
…20255)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349
vaadin-bot pushed a commit that referenced this pull request Oct 18, 2024
…20255)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349
vaadin-bot pushed a commit that referenced this pull request Oct 18, 2024
…20255)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349
vaadin-bot added a commit that referenced this pull request Oct 18, 2024
…20255) (#20278)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349

Co-authored-by: Archie L. Cobbs <archie.cobbs@gmail.com>
vaadin-bot added a commit that referenced this pull request Oct 18, 2024
…20255) (#20280)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349

Co-authored-by: Archie L. Cobbs <archie.cobbs@gmail.com>
vaadin-bot added a commit that referenced this pull request Oct 18, 2024
…20255) (#20281)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349

Co-authored-by: Archie L. Cobbs <archie.cobbs@gmail.com>
vaadin-bot added a commit that referenced this pull request Oct 18, 2024
…20255) (#20282)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349

Co-authored-by: Archie L. Cobbs <archie.cobbs@gmail.com>
mshabarov pushed a commit that referenced this pull request Oct 18, 2024
…20255) (#20279)

Commands enqueued by VaadinSession.access() in general have nothing to do with each other. The only thing they have in common is they share the same VaadinSession (and, by implication, VaadinService).

Therefore, if command №1 invoked UI.setCurrent() and command №2 invokes UI.getCurrent(), command №2 should read null, not the random UI from command №1 that it has nothing to do with.

Fixes #6349

Co-authored-by: Archie L. Cobbs <archie.cobbs@gmail.com>
mcollovati added a commit to vaadin/testbench that referenced this pull request Oct 23, 2024
…e in access() commands

When executing access enqueued command, Flow clear all thread locals
in CurrentInstance (vaadin/flow#20255), so VaadinRequest and
VaadinResponse will never be available.
mcollovati added a commit to vaadin/testbench that referenced this pull request Oct 23, 2024
…) commands

When executing access enqueued command, Flow clears all thread locals
in CurrentInstance (vaadin/flow#20255), so VaadinRequest and
VaadinResponse will never be available.
tepi pushed a commit to vaadin/testbench that referenced this pull request Oct 23, 2024
…) commands (#1829)

When executing access enqueued command, Flow clears all thread locals
in CurrentInstance (vaadin/flow#20255), so VaadinRequest and
VaadinResponse will never be available.
@vaadin-bot
Copy link
Collaborator

This ticket/PR has been released with Vaadin 24.6.0.alpha2 and is also targeting the upcoming stable 24.6.0 version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calling VaadinService.access or accessSynchronously leaks UI ThreadLocals
4 participants