Skip to content

Add onTimeoutException() on RetryRule and CircuitBreakerRule#4882

Merged
trustin merged 6 commits intoline:mainfrom
injae-kim:add-onResponseTimeout-on-retry-and-circuit-rule
Jun 9, 2023
Merged

Add onTimeoutException() on RetryRule and CircuitBreakerRule#4882
trustin merged 6 commits intoline:mainfrom
injae-kim:add-onResponseTimeout-on-retry-and-circuit-rule

Conversation

@injae-kim
Copy link
Copy Markdown
Contributor

@injae-kim injae-kim commented May 18, 2023

Motivation:

It would be useful to provide a way to configure retry and circuit breaker
rules to trigger than a request is timed out, before fully receving a response.

Modifications:

  • Add .onTimeoutException() to RetryRule and CircuitBreakerRule

Result:

PRs Overview

  • ✅ Add onTimeoutException() to RetryRule and CircuitBreakerRuleto
  • (TODO) CancellationScheduler.finishNow(TimeoutException) on session/connection timeout to set ctx.isTimeOut=true

Copy link
Copy Markdown
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 questions 🙏

Comment thread core/src/main/java/com/linecorp/armeria/client/AbstractRuleBuilder.java Outdated
public AbstractRuleBuilder onResponseTimeout() {
return onException((ctx, ex) -> {
if (ex instanceof UnprocessedRequestException) {
return ex.getCause() instanceof TimeoutException;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Question) Couldn't ctx.isTimedOut() still be true?

Suggested change
return ex.getCause() instanceof TimeoutException;
ex = ex.getCause();

Copy link
Copy Markdown
Contributor

@ikhoon ikhoon May 22, 2023

Choose a reason for hiding this comment

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

Question) Couldn't ctx.isTimedOut() still be true?

No, it isn't. It is listed in the TODO on #4876 (comment)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

(TODO) CancellationScheduler.finishNow(TimeoutException) on session/connection timeout to set ctx.isTimeOut=true

(Checked with ikhoon nim before) currently I think session/connection timeout doesn't set ctx.isTimeout=true, so I plan to fix it with next PR~!

@jrhee17 jrhee17 added this to the 1.24.0 milestone May 22, 2023
@injae-kim injae-kim requested review from ikhoon and jrhee17 May 23, 2023 04:50
Copy link
Copy Markdown
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.

Overall, looks good.

Comment thread core/src/main/java/com/linecorp/armeria/client/retry/RetryRule.java Outdated
Comment thread core/src/main/java/com/linecorp/armeria/client/retry/RetryRule.java Outdated
Comment thread core/src/main/java/com/linecorp/armeria/client/retry/RetryRuleBuilder.java Outdated
Comment thread core/src/main/java/com/linecorp/armeria/client/retry/RetryRule.java
Copy link
Copy Markdown
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.

Left a minor question but looks good to me 👍 Thanks @injae-kim 🙇 👍 🚀

Comment thread core/src/main/java/com/linecorp/armeria/client/retry/RetryRule.java Outdated
Comment on lines +186 to +187
return ex instanceof UnprocessedRequestException &&
ex.getCause() instanceof TimeoutException;
Copy link
Copy Markdown
Contributor

@jrhee17 jrhee17 May 23, 2023

Choose a reason for hiding this comment

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

Question since I'm not sure either) Do we also want to check for cases where a TimeoutException is thrown directly from a upstream decorator? e.g. ConcurrencyLimitTimeoutException

Suggested change
return ex instanceof UnprocessedRequestException &&
ex.getCause() instanceof TimeoutException;
return ex instanceof TimeoutException ||
ex instanceof UnprocessedRequestException &&
ex.getCause() instanceof TimeoutException;

Ignore this comment 😅

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't we do this? If users manually complete the response exceptionally with a ResponseTimeoutException from a decorator, it wouldn't work.
This might also confuse users that onTimeoutException() is invoked only when the exception is wrapped with the UnprocessedRequestException even though it isn't.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If users manually complete the response exceptionally with a ResponseTimeoutException from a decorator, it wouldn't work.

oh~ this case can happen. @ikhoon nim, WDYT? (how about check ex instanceof TimeoutException too?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If users manually complete the response exceptionally with a ResponseTimeoutException from a decorator, it wouldn't work.

Hmm... ResponseTimeoutException is a special exception to cancel a response based on the timeout stored in ctx.responseTimeoutMillis(). If a user raises ResponseTimeoutException, it should be assumed as a normal exception but neither a timeout exception or a cancellation exception.

This might also confuse users that onTimeoutException() is invoked only when the exception is wrapped with the UnprocessedRequestException even though it isn't.

If we update the contract of ctx.isTimedOut() properly, I don't see users get confused of the behavior. They may not judge the behavior by the implementation.

Anyway, it is good to add ex instanceof TimeoutException in this PR because ctx.isTimedOut() doesn't cover WriteTimeoutException and ConcurrencyLimitTimeoutException even though we will handle them in the following PR.
Let's make this PR solid itself.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Anyway, it is good to add ex instanceof TimeoutException in this PR

✅ updated!

Copy link
Copy Markdown
Contributor

@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.

Looks great all in all. 👍
Left just a small opinion.

Comment on lines +186 to +187
return ex instanceof UnprocessedRequestException &&
ex.getCause() instanceof TimeoutException;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't we do this? If users manually complete the response exceptionally with a ResponseTimeoutException from a decorator, it wouldn't work.
This might also confuse users that onTimeoutException() is invoked only when the exception is wrapped with the UnprocessedRequestException even though it isn't.

Copy link
Copy Markdown
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! 🙇‍♂️

Copy link
Copy Markdown
Contributor

@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.

Looks good all in all, thanks a lot! @injae-kim
BTW, could you revise the title and the description of this PR? 😄

@injae-kim injae-kim changed the title Add onResponseTimeout() on RetryRule and CircuitBreakerRule Add onTimeoutException() on RetryRule and CircuitBreakerRule Jun 2, 2023
@injae-kim
Copy link
Copy Markdown
Contributor Author

oh~ I updated PR title&desc, onResponseTimeout -> onTimeoutException!

Copy link
Copy Markdown
Member

@trustin trustin left a comment

Choose a reason for hiding this comment

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

Lovely! Thanks, @injae-kim 🙇

@trustin trustin merged commit 9b831fb into line:main Jun 9, 2023
ikhoon pushed a commit to be-hase/armeria that referenced this pull request Jun 12, 2023
…4882)

Motivation:

It would be useful to provide a way to configure retry and circuit
breaker
rules to trigger than a request is timed out, before fully receving a
response.

Modifications:
- Add `.onTimeoutException()` to `RetryRule` and `CircuitBreakerRule`

Result:
- You can use `.onTimeoutException()` on RetryRule and
CircuitBreakerRule when a request is timed out before fully receiving a
response.
- Closes line#4876
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add RetryRule.onResponseTimeout()

5 participants