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

Set RequestContext.isTimedOut(true) on DNS, session, write timeout #5156

Merged
merged 2 commits into from
Aug 2, 2024

Conversation

injae-kim
Copy link
Contributor

Related issue #4935

Motivation:

We need to make sure CancellationScheduler.finishNow(TimeoutException) is invoked on more timeout types,
such as session/connection/DNS timeout so that true is set to ctx.isTimedOut().

Modifications:

  • Set RequestContext.isTimedOut(true) on DNS, session, write timeout by ctx.cancel(TimeoutException.class)

Result:

@codecov
Copy link

codecov bot commented Aug 29, 2023

Codecov Report

Attention: Patch coverage is 50.00000% with 13 lines in your changes missing coverage. Please review.

Project coverage is 73.92%. Comparing base (863e27c) to head (084bf58).
Report is 387 commits behind head on main.

Files Patch % Lines
...rmeria/client/SessionCreationTimeoutException.java 0.00% 10 Missing ⚠️
...ia/client/SessionProtocolNegotiationException.java 66.66% 1 Missing and 1 partial ⚠️
.../linecorp/armeria/client/ClientRequestContext.java 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #5156      +/-   ##
============================================
- Coverage     74.25%   73.92%   -0.34%     
- Complexity    19825    20023     +198     
============================================
  Files          1699     1722      +23     
  Lines         73046    73899     +853     
  Branches       9357     9406      +49     
============================================
+ Hits          54239    54628     +389     
- Misses        14371    14820     +449     
- Partials       4436     4451      +15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@injae-kim injae-kim force-pushed the set-reqctx-istimedout-true branch 2 times, most recently from 92426fb to d58b565 Compare September 1, 2023 08:04
.build();

assertThat(reqCtx.isTimedOut()).isFalse();
assertThatThrownBy(() -> client.unwrap().execute(reqCtx, req).aggregate().join())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
assertThatThrownBy(() -> client.unwrap().execute(reqCtx, req).aggregate().join())
assertThatThrownBy(() -> client.get("/").aggregate().join())

Hmm when I use WebClient.get("/") directly, reqCtx.whenResponseCancelled().join() not done infinitely 🤔

responseCancellationScheduler.init(eventLoop(), noopCancellationTask, 0, /* server */ false);

I guess ClientRequestContextBuilder().build() init cancellationScheduler immediately, but WebClient didn't.

this.responseCancellationScheduler =
new CancellationScheduler(TimeUnit.MILLISECONDS.toNanos(responseTimeoutMillis));

On WebClient, it uses DefaultClientRequestContext and it doesn't init() the ClientRequestContext's cancellationScheduler immediately.
Just add task (e.g. ctx.cancel(cause)) to pending task and execute it on init() lazily later like below.

if (pendingTaskUpdater.compareAndSet(this, pendingTask, noopPendingTask)) {
if (pendingTask != null) {
pendingTask.run();
}

But to get reqCtx.whenCancelled() completion, we need to init() cancellationScheduler.

So I used client.unwarp().execuite(reqCtx) to use ClientRequestContext.builder().build() to init cancellationScheduler~!

I'm not sure it's correct, so feel free to share your opinion! I'll update PR 🙇

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe you can just use Clients.newContextCaptor() if you would like to get ahold of the RequestContext being used

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh I tried to use Clients.newContextCaptor() but cancellationScheduler is still not init() by this way so ClientRequestContext.isTimedOut() return false 😅

Copy link
Contributor

@jrhee17 jrhee17 left a comment

Choose a reason for hiding this comment

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

Looks good overall! Left some minor comments 🙇

.build();

assertThat(reqCtx.isTimedOut()).isFalse();
assertThatThrownBy(() -> client.unwrap().execute(reqCtx, req).aggregate().join())
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe you can just use Clients.newContextCaptor() if you would like to get ahold of the RequestContext being used

Copy link
Contributor

@jrhee17 jrhee17 left a comment

Choose a reason for hiding this comment

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

Took another look at this PR.

The way I see it there are two options (or actually three):

  1. Use log.responseCause to determine whether a request/response has timed out (or actually log().getIfAvailable(RequestLogProperty.RESPONSE_CAUSE).responseCause();)
  2. Modify responseCancellationScheduler so that either
    1.init is called at an earlier timing. Ideally, this would involve scheduling timeouts for each step (dns, connect, write, etc..) using ctx.cancellationScheduler.
    2. modify the behavior so that cancel() also executes pending tasks.

I think 1 or 2-2 is probably a realistic direction for this PR. Let me discuss with the other tomorrow morning 🙇

@injae-kim
Copy link
Contributor Author

I think 1 or 2-2 is probably a realistic direction for this PR. Let me discuss with the other tomorrow morning

If there's some discussion progress about direction, feel free to share to me~! 🙇

@minwoox
Copy link
Member

minwoox commented Oct 10, 2023

We have decided to go with the second option. @jrhee17 is laying the groundwork for that.
#5212
He will let you know when it's done. 😉

@injae-kim
Copy link
Contributor Author

We have decided to go with the second option

aha~ I checked #5212. thanks for sharing!
feel free to let me know when it's ready to go with the 2. option~! 🙇

@minwoox minwoox added this to the 1.27.0 milestone Oct 11, 2023
@ikhoon ikhoon modified the milestones: 1.27.0, 1.28.0 Jan 16, 2024
@minwoox
Copy link
Member

minwoox commented Apr 2, 2024

Since #5212 has been completed, perhaps we can resume this work now?
cc @jrhee17

@jrhee17 jrhee17 modified the milestones: 1.28.0, 1.29.0 Apr 2, 2024
@injae-kim
Copy link
Contributor Author

oh~ I'll update this PR on this weekend. thanks! :)

@github-actions github-actions bot added the Stale label May 5, 2024
@minwoox minwoox modified the milestones: 1.29.0, 1.30.0 May 21, 2024
@github-actions github-actions bot removed the Stale label May 23, 2024
@github-actions github-actions bot added the Stale label Jun 22, 2024
@github-actions github-actions bot removed the Stale label Jul 5, 2024
@injae-kim injae-kim requested a review from jrhee17 July 5, 2024 07:59
@injae-kim
Copy link
Contributor Author

Since #5212 has been completed, perhaps we can resume this work now?

@jrhee17, I updated this PR to latest based on #5212~! PTAL 🙇

Copy link
Contributor

@jrhee17 jrhee17 left a comment

Choose a reason for hiding this comment

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

Changes look good to me 👍 👍 👍

Copy link
Member

@minwoox minwoox left a comment

Choose a reason for hiding this comment

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

Just one nit. Thank! 😄

Copy link
Contributor

@ikhoon ikhoon left a comment

Choose a reason for hiding this comment

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

Thanks, @injae-kim! 🙇‍♂️🙇‍♂️

@ikhoon ikhoon merged commit 4c6f0ff into line:main Aug 2, 2024
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

A DnsTimeoutException should also set true to ctx.isTimedOut().
4 participants