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

[Stack Monitoring] Ensure GlobalState class has it's destroy() method called on unmount #139908

Merged
merged 5 commits into from
Sep 6, 2022

Conversation

Kerry350
Copy link
Contributor

@Kerry350 Kerry350 commented Sep 1, 2022

Summary

This fixes #135136 (and other related problems, e.g. #139231 (comment)).

Whilst the GlobalState class (which syncs to the URL) had a destroy() method, it wasn't being called. This is now called on unmount of the top-level <GlobalStateProvider />.

Testing

I was able to consistently replicate the bug by doing the following:

  1. Navigate to Discover
  2. Navigate to Stack Monitoring
  3. Navigate back to Discover
  4. Interact with the "Refresh every" toggle of the timepicker (either turn it off or on, it's the change of the refresh that matters)

This should throw a routing error without this PR.

@Kerry350 Kerry350 added Team:Infra Monitoring UI - DEPRECATED DEPRECATED - Label for the Infra Monitoring UI team. Use Team:obs-ux-infra_services Feature:Stack Monitoring v8.5.0 v8.4.2 labels Sep 1, 2022
@Kerry350 Kerry350 requested a review from a team as a code owner September 1, 2022 11:17
@Kerry350 Kerry350 self-assigned this Sep 1, 2022
@elasticmachine
Copy link
Contributor

Pinging @elastic/infra-monitoring-ui (Team:Infra Monitoring UI)

Copy link
Contributor

@Dosant Dosant left a comment

Choose a reason for hiding this comment

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

Thanks for fixing this!

While investigating this here #139231 (comment), I also noticed that this component creates GlobalState as a local variable during rendering instead of creating it once during mount:

const state = new GlobalState(query, toasts, localState as { [key: string]: unknown });

I think this also could be a problem as this can be called multiple times, and we clean up only the last state when the component unmounts.

Should we put this state into useRef? Or into the useState?

@Kerry350
Copy link
Contributor Author

Kerry350 commented Sep 5, 2022

@Dosant

I think this also could be a problem as this can be called multiple times, and we clean up only the last state when the component unmounts.

Yeah, that's a good point. Technically this component should only mount and render once given the Provider hierarchy. But it is susceptible to a subtle change somewhere upstream causing re-renders.

I've moved the instantiation into a useState call to keep the integrity between renders, if they were to happen.

I did also look at cleaning up localState too (the Angular > React conversion resulted in some code that wasn't idiomatic), but the object gets manipulated with raw property updates all throughout the codebase, so it's not a trivial change. Whilst not ideal if there were to be a re-render this one just leads to a small performance hit to recreate the objects rather than subscription leakage. Given the Platform Observability project now has priority over SM I think we can leave this bit as is.

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
monitoring 504 506 +2

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
monitoring 478.0KB 478.5KB +449.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
monitoring 23.8KB 23.8KB +49.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @Kerry350

Copy link
Contributor

@Dosant Dosant left a comment

Choose a reason for hiding this comment

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

Thanks!

@Kerry350 Kerry350 merged commit 875a624 into elastic:main Sep 6, 2022
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Sep 6, 2022
… called on unmount (elastic#139908)

* Ensure GlobalState class has it's destroy() method called

* Move GlobalState instantiation to useState

Co-authored-by: Anton Dosov <[email protected]>
(cherry picked from commit 875a624)
@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.4

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Sep 6, 2022
… called on unmount (#139908) (#140133)

* Ensure GlobalState class has it's destroy() method called

* Move GlobalState instantiation to useState

Co-authored-by: Anton Dosov <[email protected]>
(cherry picked from commit 875a624)

Co-authored-by: Kerry Gallagher <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Stack Monitoring release_note:fix Team:Infra Monitoring UI - DEPRECATED DEPRECATED - Label for the Infra Monitoring UI team. Use Team:obs-ux-infra_services v8.4.2 v8.5.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Stack Monitoring] Intermittent error when access a dashboard from any Stack Monitoring page
6 participants