-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Logs UI] Add helper hooks with search strategy request cancellation #83906
[Logs UI] Add helper hooks with search strategy request cancellation #83906
Conversation
fbdc783
to
d6db953
Compare
55eb746
to
11d7b79
Compare
d9f6709
to
9af62cd
Compare
9af62cd
to
b4b4ff9
Compare
Pinging @elastic/logs-metrics-ui (Team:logs-metrics-ui) |
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.
On a first pass the code looks good. I don't feel comfortable yet commenting on the RxJS parts but I promise I'll give it a shot tomorrow :D.
One thing I've noticed that I'm not sure it matters in practical effects: there seems to be a distinction between explicitly aborting a request and implicitly doing it when the containing component unmounts.
When the request is explicitly cancelled, there's an extra DELETE
request, probably made to do housekeeping. However, when the component unmounts (by closing the flyout, for example), this request doesn't seem to happen.
x-pack/plugins/infra/public/components/data_search_error_callout.tsx
Outdated
Show resolved
Hide resolved
x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_fields_table.tsx
Outdated
Show resolved
Hide resolved
x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx
Outdated
Show resolved
Hide resolved
x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx
Show resolved
Hide resolved
x-pack/plugins/infra/public/components/logging/log_entry_flyout/log_entry_flyout.tsx
Outdated
Show resolved
Hide resolved
logEntryId: string | null | undefined; | ||
}) => { | ||
const { search: fetchLogEntry, requests$: logEntrySearchRequests$ } = useDataSearch({ | ||
getRequest: useCallback(() => { |
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.
Is the useCallback
required here? What would happen if the identity of this function changes?
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.
The consequence is that the returned search()
function's identity changes every render. That's probably not a problem depending on the downstream use of search
. So this is a performance optimization.
if (newUrlState && newUrlState.flyoutId) { | ||
setFlyoutId(newUrlState.flyoutId); | ||
setLogEntryId(newUrlState.flyoutId); | ||
} | ||
if (newUrlState && newUrlState.surroundingLogsId) { | ||
setSurroundingLogsId(newUrlState.surroundingLogsId); | ||
} | ||
if (newUrlState && newUrlState.flyoutVisibility === FlyoutVisibility.visible) { | ||
setFlyoutVisibility(true); | ||
openFlyout(); | ||
} | ||
if (newUrlState && newUrlState.flyoutVisibility === FlyoutVisibility.hidden) { | ||
setFlyoutVisibility(false); | ||
closeFlyout(); | ||
} | ||
}} |
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 think we can simplify this block a bit. What do you think?
if (newUrlState && newUrlState.flyoutId && newUrlState.flyoutVisibility === FlyoutVisibility.visible) {
openFlyout(newUrlState.flyoutId);
}
if (newUrlState && newUrlState.flyoutVisibility === FlyoutVisibility.hidden) {
closeFlyout();
}
if (newUrlState && newUrlState.surroundingLogsId) {
setSurroundingLogsId(newUrlState.surroundingLogsId);
}
That way I think that we no longer need to expose the setLogEntryId()
callback from useLogEntryFlyoutContext()
There's something about this block that github doesn't like; it doesn't let me add a suggestion.
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.
But wouldn't that mean that we can't represent the scenario that the URL contains a flyoutId
but the visibility is false
? I personally don't like that split anyway, but I wonder how risky it would be to change the URL semantics.
if (initialUrlState && initialUrlState.flyoutId) { | ||
setFlyoutId(initialUrlState.flyoutId); | ||
setLogEntryId(initialUrlState.flyoutId); | ||
} | ||
if (initialUrlState && initialUrlState.surroundingLogsId) { | ||
setSurroundingLogsId(initialUrlState.surroundingLogsId); | ||
} | ||
if (initialUrlState && initialUrlState.flyoutVisibility === FlyoutVisibility.visible) { | ||
setFlyoutVisibility(true); | ||
openFlyout(); | ||
} | ||
if (initialUrlState && initialUrlState.flyoutVisibility === FlyoutVisibility.hidden) { | ||
setFlyoutVisibility(false); | ||
closeFlyout(); | ||
} |
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.
Similar to above
That's an interesting observation. I suspect it's a matter of timing. The |
That seems the case. If I cancel the request when the "Searching log entries in shards" message appears, it always sends a I don't think it's a big issue, but we can check with the data plugin owners to see if it is. If that's the case we can always fix it after feature freeze. |
It might indicate that we're leaking async search results on the ES side, so it could become a performance or stability problem. I'll investigate further. |
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.
Although I couldn't take a deep look at all the RxJS-related code, I feel comfortable approving the PR to move forward since the code works as intended.
I can take a look later at the code and write a proposal with changes if I find anything :)
Good job. LGTM!
💚 Build SucceededMetrics [docs]Module Count
Async chunks
Distributable file count
Page load bundle
History
To update your PR or re-run it, just comment with: |
Summary
This adds helper React hooks for interacting with
data
plugin search strategies. Using these hooks the log entry fly-out now indicates the loading progress, shows errors and cancels requests when closed.closes #78003
Release Notes
Displays progress for asynchronous loading of the log entry fly-out content and cancels pendig requests when closing the fly-out.
Review and implementation notes
The log entry fly-out structure has been cleaned up to remove timing issues and avoid eager fetching.
The fly-out now sports a loading progress bar with the option to cancel the running request. The request is also canceled when the fly-out is closed while loading is in progress. The cancellation can take the form of a canceled request if one is pending. Otherwise it just means that no further polling of the async results is performed.
To achieve that I'm tried to build a toolbox of hooks and components that can be used in future async search requests as well:
The producer hook
useDataSearch
spawns new requests usingdata.search.search
and returns an observable that emits an object describing each new request. The response observables associated with each request are amended such that unsubscribing from them leads to cancellation of pending requests and polling cycles.The consumer hook
useLatestPartialDataSearchRequest
consumes that observable and subscribes to each request's response observable in a way that...Some utility hooks form the glue between observables and the react rendering cycle. Among them are
useObservable
to create stablepipe()
s,useSubscription
to tie a subscription to the component life-cycle anduseObservableState
to turn an observable's emitted values into React component state.Several new "data search" stories in the
infra
storybook showcase some of the components used in the fly-out. They consist of a progress bar, an error call-out and fly-out layout helpers.I tried to expand on the above description in a MDX storybook, which can be built using
yarn storybook infra
.Previews
Display progress based on the searched/total number of shards:
Display errors that occur during loading without partial results available: (this weird error message is caused by the chrome devtools request blocking feature and will differ depending on the cause of the failure)
Display a mixture of partial results and shard failures:
Task breakdown