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

[APM] Abort browser requests when appropriate #89557

Merged
merged 7 commits into from
Feb 2, 2021

Conversation

dgieselaar
Copy link
Member

Closes #81740.

@dgieselaar dgieselaar added release_note:skip Skip the PR/issue when compiling release notes v7.12.0 labels Jan 28, 2021
@dgieselaar dgieselaar requested review from a team as code owners January 28, 2021 13:39
@botelastic botelastic bot added Team:APM All issues that need APM UI Team support Team:Uptime - DEPRECATED Synthetics & RUM sub-team of Application Observability labels Jan 28, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/uptime (Team:uptime)

@elasticmachine
Copy link
Contributor

Pinging @elastic/apm-ui (Team:apm)

Copy link
Contributor

@justinkambic justinkambic left a comment

Choose a reason for hiding this comment

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

I'm rubber stamping this because it triggered a CODEOWNER review on one file. I'm operating under the assumption if signal: null poses no threat to the rest of the routes changed it will operate similarly in the UX API.

@@ -39,6 +42,14 @@ function getDetailsFromErrorResponse(error: IHttpFetchError) {
);
}

const createLifecycleManagedCallApmApi = (
Copy link
Member

Choose a reason for hiding this comment

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

nit (suggestion)

Suggested change
const createLifecycleManagedCallApmApi = (
const createAbortableApmApiClient = (

Copy link
Member Author

Choose a reason for hiding this comment

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

I considered this, but every ApmApiClient's calls are abortable, if you pass a signal. This one takes care of aborting for you. So I'm not sure if createAbortableApmApiClient is better here. But I agree that createLifecycleManagedCallApmApi is not great.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, okay. Would it make sense to call it createAutoAbortableApmClient or something like that? "lifecycle" is pretty very vague, and not something I'd immediately associate with the request being aborted automatically.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed, let me think about it, I think that's one better at least.

@@ -39,6 +42,14 @@ function getDetailsFromErrorResponse(error: IHttpFetchError) {
);
}

const createLifecycleManagedCallApmApi = (
signal: AbortSignal
): LifecycleManagedAPMClient => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
): LifecycleManagedAPMClient => {
): AbortableAPMClient => {

@@ -48,7 +59,7 @@ type InferResponseType<TReturn> = Exclude<TReturn, undefined> extends Promise<
: unknown;

export function useFetcher<TReturn>(
fn: (callApmApi: APMClient) => TReturn,
fn: (callApmApi: LifecycleManagedAPMClient) => TReturn,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
fn: (callApmApi: LifecycleManagedAPMClient) => TReturn,
fn: (apmApiClient: AbortableAPMClient) => TReturn,

@@ -130,7 +148,7 @@ export function useFetcher<TReturn>(
doFetch();

return () => {
didCancel = true;
controller.abort();
Copy link
Member

Choose a reason for hiding this comment

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

What will the FETCH_STATUS state be when a request is aborted? Should we introduce a new state or is that overkill (I'd rather not if we can avoid it).

Copy link
Member Author

Choose a reason for hiding this comment

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

Aborted is not necessarily a state here, it can be a result of a new request, the component unmounting, or the useFetcher cb not returning a promise. We were already "soft-canceling" requests before, so I don't think this change should affect state but I'll think about it for a bit.

Copy link
Member

@sorenlouv sorenlouv Jan 29, 2021

Choose a reason for hiding this comment

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

Okay. I was trying to think through if we still needed the if (!signal.aborted) { checks. Previously, if useFetcher props changed, we used didCancel = true to avoid updating the state when the underlying request (which didn't get cancelled) returned.
Since we are now actually cancelling the request, will useFetcher still re-render upon cancellation (or some later stage) or can we omit the checks?

Copy link
Member Author

Choose a reason for hiding this comment

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

We might not need the first one. But the second one we do, as the promise will be rejected when the request is aborted.

@@ -12,11 +12,17 @@ import { APMAPI } from '../../../server/routes/create_apm_api';
import { Client } from '../../../server/routes/typings';

export type APMClient = Client<APMAPI['_S']>;
export type LifecycleManagedAPMClient = Client<
APMAPI['_S'],
{ lifecycleManaged: true }
Copy link
Member

@sorenlouv sorenlouv Jan 29, 2021

Choose a reason for hiding this comment

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

Suggested change
{ lifecycleManaged: true }
{ isAbortable: true }

Copy link
Member

@sorenlouv sorenlouv left a comment

Choose a reason for hiding this comment

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

LGTM!

When I started in Elastic in 2017 we couldn't use this feature because it wasn't well supported. So nice to see how the web is still moving forward - I sometimes forget that :D

image

Copy link
Member

@sorenlouv sorenlouv left a comment

Choose a reason for hiding this comment

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

lgtm. Just on question around how cancellation affects re-rendering.

@dgieselaar
Copy link
Member Author

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
apm 1739 1738 -1

Async chunks

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

id before after diff
apm 5.2MB 5.2MB -602.0B

History

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

@dgieselaar dgieselaar merged commit 2a4d39a into elastic:master Feb 2, 2021
@dgieselaar dgieselaar deleted the cancel-browser-request branch February 2, 2021 13:44
dgieselaar added a commit to dgieselaar/kibana that referenced this pull request Feb 2, 2021
dgieselaar added a commit that referenced this pull request Feb 2, 2021
phillipb added a commit to phillipb/kibana that referenced this pull request Feb 2, 2021
…-ml-jobs

* 'master' of github.com:elastic/kibana: (254 commits)
  [Security Solution] [Detections] Remove allow_no_indices to prevent error being thrown in response of field capabilities (elastic#89927)
  Skip test for cloud (elastic#89450)
  [Fleet] Fix duplicate data streams being shown in UI (elastic#89812)
  Bump package dependencies (elastic#90034)
  [App Search] DRY helper for encoding/decoding routes that can have special characters in params (elastic#89811)
  TypeScript project references for Observability plugin (elastic#89320)
  [SearchSource] Combine sort and parent fields when serializing (elastic#89808)
  Made imports static (elastic#89935)
  [ml] migrate file_data_visualizer/import route to file_upload plugin (elastic#89640)
  [Discover] Adapt default column behavior (elastic#89826)
  Round start and end values (elastic#89030)
  Rename getProxyAgents to getCustomAgents (elastic#89813)
  [Form lib] UseField `onError` listener (elastic#89895)
  [APM] use latency sum instead of avg for impact (elastic#89990)
  migrate more core-owned plugins to tsproject ref (elastic#89975)
  [Logs UI] Load <LogStream> entries via async searches (elastic#86899)
  [APM] Abort browser requests when appropriate (elastic#89557)
  [Alerting] Allow user to select existing connector of same type when fixing broken connector (elastic#89062)
  [Data Table] Use shared CSV export mechanism (elastic#89702)
  chore(NA): improve logic check when installing Bazel tools (elastic#89634)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:skip Skip the PR/issue when compiling release notes Team:APM All issues that need APM UI Team support Team:Uptime - DEPRECATED Synthetics & RUM sub-team of Application Observability v7.12.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[APM] Cancel requests (both server-side and browser-side)
5 participants