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

[Security Solution][Case] Improve hooks #89580

Merged
merged 3 commits into from
Feb 25, 2021

Conversation

cnasikas
Copy link
Member

@cnasikas cnasikas commented Jan 28, 2021

Summary

We found a problem around our paradigm in case hooks. The problem was that useCallback does not know when a component is going unmounted, however useEffect does know all the secrets/ life cycle of a component therefore we are taking advantage of it.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@cnasikas cnasikas added v8.0.0 release_note:skip Skip the PR/issue when compiling release notes v7.12.0 Team:Threat Hunting Security Solution Threat Hunting Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. labels Jan 28, 2021
@cnasikas cnasikas self-assigned this Jan 28, 2021
@cnasikas cnasikas requested review from a team as code owners January 28, 2021 15:31
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-threat-hunting (Team:Threat Hunting)

@cnasikas cnasikas marked this pull request as draft January 28, 2021 15:32
@cnasikas cnasikas force-pushed the fix_case_hooks branch 2 times, most recently from e988d60 to 1ddae60 Compare February 11, 2021 09:45
@cnasikas cnasikas marked this pull request as ready for review February 11, 2021 09:47
@cnasikas cnasikas requested a review from a team as a code owner February 11, 2021 09:47
@cnasikas cnasikas added Team:Threat Hunting Security Solution Threat Hunting Team and removed Team:Threat Hunting Security Solution Threat Hunting Team labels Feb 11, 2021
@cnasikas cnasikas requested a review from a team February 15, 2021 15:34
Copy link
Contributor

@ecezalp ecezalp left a comment

Choose a reason for hiding this comment

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

Hi! This is Ece, new hire on Threat Intelligence. This is my first review! I will keep it comment only until I get ramped up - I would sincerely appreciate a review of my review :)

Reading through the changes, I had a couple of thoughts

  • naming of didCancel
    usually booleans are prefixed with is, so if didCancel remained a boolean, I would have suggested a name such as isCancelled. However it looks like didCancel became a ref. In React docs refs are usually indicated with a Ref suffix (myRef, inputRef in Refs and the DOM) this is by no means necessary, but I personally like having that visual indicator as a reminder to always read .current of something that is clearly a fooRef. Therefore, I think that didCancel could also be called didCancelRef or even isCancelledRef - whichever works best.
  • reoccurence and similar usage of didCancel and abortCtrl refs
    it looks like we could create a new hook that encapsulates the declaration of didCancel and abortCtrl refs, as well as the cleanup func, which could be used in multiple hooks that are being tidied up in this PR. In fact, [isLoading, setIsLoading] could also be a part of the new hook, which could be called something along the lines of useAbortableRequest.
  • error.name !== 'AbortError' check
    it looks like we always check !didCancel.current beforehand, so if the request is aborted, we won't be executing this block anyway, so the check seems useless unless there is any other scenario in which a request can get aborted outside of the cleanup with the AbortCtrl call.
  • cancelToken
    I am not particularly familiar with this codebase - with a quick look, it looks like the AbortController is creating an event called "abort", and 'things' get set in motion from thereon. I would have assumed that a cancelToken would be generated when the request is being made, and that cancelToken could be called to cancel the request if the user navigated away from the page, instead of an AbortController call to take care if this - I would be very happy to learn more about this pattern. I am assuming that the abort event is being caught by a middleware, will follow up with this to broaden my understanding.

@cnasikas
Copy link
Member Author

cnasikas commented Feb 19, 2021

Hey! Welcome to the team Ece! Feel free to leave comments on the code.

naming of didCancel

Ok!

reoccurence and similar usage of didCancel and abortCtrl refs

I think this is a scenario where duplication is better than deduplication. The reason is that useEffect's can sometimes can be unpredicted or easy to introduced bugs if not used correctly. I think, in this type of hooks, is better to have isolated hooks than hooks that share logic from other hooks. Imagine we have to fix a bug on a hook. It is easier to do the fix and debug in one hook rather than to have to do the fix in a generic hooks that all other hooks will be affected. It will be difficult to test and to be sure that the fix will not create other bugs to other hooks. I think isolation is better and it can justify the duplication.

error.name !== 'AbortError'

I had the same thought at first 😄! Imagine a user clicks a button to submit and then press the button again very fast before the first request has been fulfilled. In this scenario the first call will be canceled, as we abortController.current.abort(), and an AbortError is throw. didCancel.current is false so it will show the toaster. With error.name !== 'AbortError' we make sure that will not happen. Another scenario that could occurred (although, I am not 100% sure and maybe I am wrong) is when a component re-renders very fast and a request is made in the first render but in the second re-render the first request is being canceled and a second one initiates.

cancelToken

AbortController is part of the Web API and it can be used to abort request at will. fetch is implemented in a way that if a signal (AbortSignal) is provided it listen to this event and aborts when the event is fired (abortController.abort()).

Copy link
Contributor

@kqualters-elastic kqualters-elastic left a comment

Choose a reason for hiding this comment

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

Agree that these hooks and many others in the plugin seem like there is ample opportunity for a shared hook or two to remove some of the identical code, but this fixes the loading bug and bug with no cleanup logic running when the consuming component is destroyed so lgtm 👍

@cnasikas
Copy link
Member Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

merge conflict between base and head

@cnasikas
Copy link
Member Author

@elasticmachine merge upstream

@cnasikas cnasikas added v7.13.0 bug Fixes for quality problems that affect the customer experience labels Feb 24, 2021
@cnasikas
Copy link
Member Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Async chunks

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

id before after diff
securitySolution 7.7MB 7.8MB +4.7KB

History

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

cc @cnasikas

@cnasikas cnasikas merged commit a3760ce into elastic:master Feb 25, 2021
@cnasikas cnasikas deleted the fix_case_hooks branch February 25, 2021 16:30
cnasikas added a commit to cnasikas/kibana that referenced this pull request Feb 25, 2021
cnasikas added a commit to cnasikas/kibana that referenced this pull request Feb 25, 2021
# Conflicts:
#	x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.tsx
jloleysens added a commit to jloleysens/kibana that referenced this pull request Feb 25, 2021
…tiple-searchable-snapshot-actions

* 'master' of github.com:elastic/kibana:
  [Rollup] Fix use of undefined value in JS import (elastic#92791)
  [ILM] Fix replicas not showing  (elastic#92782)
  [Event Log] Extended README.md with the documentation for a REST API and Start plugin contract. (elastic#92562)
  [XY] Enables page reload toast for the legacyChartsLibrary setting (elastic#92811)
  [Security Solution][Case] Improve hooks (elastic#89580)
  [Security Solution] Update wordings and breadcrumb for timelines page (elastic#90809)
  [Security Solution] Replace EUI theme with mocks in jest suites (elastic#92462)
  docs: ✏️ use correct heading level (elastic#92806)
  [ILM ] Fix logic for showing/hiding recommended allocation on Cloud (elastic#90592)
  [Security Solution][Detections] Pull gap detection logic out in preparation for sharing between rule types (elastic#91966)
  [core.savedObjects] Remove _shard_doc tiebreaker since ES now adds it automatically. (elastic#92295)
  docs: ✏️ fix links in embeddable plugin readme (elastic#92778)

# Conflicts:
#	x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx
cnasikas added a commit that referenced this pull request Feb 26, 2021
# Conflicts:
#	x-pack/plugins/security_solution/public/cases/containers/use_bulk_update_case.tsx

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Fixes for quality problems that affect the customer experience release_note:skip Skip the PR/issue when compiling release notes Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Threat Hunting Security Solution Threat Hunting Team v7.12.0 v7.13.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants