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
Move Endpoint selection to the beginning of client execution #1917
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1917 +/- ##
============================================
- Coverage 73.28% 73.26% -0.02%
- Complexity 8987 9014 +27
============================================
Files 794 798 +4
Lines 35189 35236 +47
Branches 4324 4333 +9
============================================
+ Hits 25788 25816 +28
- Misses 7193 7194 +1
- Partials 2208 2226 +18
Continue to review full report at Codecov.
|
Does it work for the failure case to set the |
That sounds good to me. We could also do the same when we move the connection pooling to the beginning. Sounds good? |
Yup :) |
97d0d24
to
a85dad1
Compare
I found it's weird to use |
That being said, I'd eventually like to make |
Yeah that makes sense |
aab1c37
to
071c4c1
Compare
Motivation: `ClientRequestContext.endpoint()` currently return an `Endpoint` which may be 1) a host:port endpoint or 2) a group endpoint. Therefore, a client decorator does not know which host the request will be sent to exactly; it is determined after all decorators are evaluated. This makes it hard for client decorators to do the following: - Injecting a header value derived from the target host name. - Accounting for the number of requests sent to each host. Modifications: - Split the initialization of `DefaultClientRequestContext` into two: 1) constructor and 2) `init()` method. - Determine the target host at the context initialization phase. - Make `ClientRequestContext.endpoint()` nullable, so that the decorators can handle the case where endpoint selection has failed. - Add `ClientRequestContext.endpointSelector()`. - Add test cases for HTTP, gRPC and Thrift. - Miscellaneous: - Add `EndpointGroup.empty()`. Result: - Client decorators now knows the exact target host of the request. - We can make `Endpoint` always refer to a host:port, which will greatly simplify both users' code and ours in the future. - We now have a proper place (`DefaultClientRequestContext.init()`) that can be used for `EventLoop` allocation and connection pooling in the future.
071c4c1
to
89528cb
Compare
core/src/main/java/com/linecorp/armeria/client/ClientRequestContext.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/DefaultClientRequestContext.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/ClientRequestContext.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/ClientRequestContext.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/DefaultClientRequestContext.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/DefaultClientRequestContext.java
Outdated
Show resolved
Hide resolved
core/src/test/java/com/linecorp/armeria/client/DefaultClientRequestContextTest.java
Show resolved
Hide resolved
grpc/src/main/java/com/linecorp/armeria/client/grpc/ArmeriaClientCall.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/retry/RetryingClient.java
Show resolved
Hide resolved
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.
Great job. 👍
logback/src/main/java/com/linecorp/armeria/common/logback/RequestContextExporter.java
Show resolved
Hide resolved
/** | ||
* Creates a new {@link ClientRequestContext} whose properties and {@link Attribute}s are copied from this | ||
* {@link ClientRequestContext}, except having a different {@link Request} and its own {@link RequestLog}. | ||
*/ |
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.
Thanks for adding missed documentation. 👍
core/src/main/java/com/linecorp/armeria/server/DefaultServiceRequestContext.java
Outdated
Show resolved
Hide resolved
...src/test/java/com/linecorp/armeria/client/circuitbreaker/KeyedCircuitBreakerMappingTest.java
Outdated
Show resolved
Hide resolved
@anuraaga I also hardened the thread safety of |
core/src/main/java/com/linecorp/armeria/client/DefaultClientRequestContext.java
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/endpoint/StaticEndpointGroup.java
Outdated
Show resolved
Hide resolved
core/src/main/java/com/linecorp/armeria/client/retry/RetryingHttpClient.java
Outdated
Show resolved
Hide resolved
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.
Thank you for awesome job!
Motivation: `ClientRequestContext.endpoint()` currently return an `Endpoint` which may be 1) a host:port endpoint or 2) a group endpoint. Therefore, a client decorator does not know which host the request will be sent to exactly; it is determined after all decorators are evaluated. This makes it hard for client decorators to do the following: - Injecting a header value derived from the target host name. - Accounting for the number of requests sent to each host. Modifications: - Split the initialization of `DefaultClientRequestContext` into two: 1) constructor and 2) `init()` method. - Determine the target host at the context initialization phase. - Make `ClientRequestContext.endpoint()` nullable, so that the decorators can handle the case where endpoint selection has failed. - Add `ClientRequestContext.endpointSelector()`. - Add test cases for HTTP, gRPC and Thrift. - Miscellaneous: - Add `EndpointGroup.empty()`. Result: - Client decorators now knows the exact target host of the request. - We can make `Endpoint` always refer to a host:port, which will greatly simplify both users' code and ours in the future. - We now have a proper place (`DefaultClientRequestContext.init()`) that can be used for `EventLoop` allocation and connection pooling in the future.
Motivation:
ClientRequestContext.endpoint()
currently return anEndpoint
whichmay be 1) a host:port endpoint or 2) a group endpoint. Therefore, a
client decorator does not know which host the request will be sent to
exactly; it is determined after all decorators are evaluated. This makes
it hard for client decorators to do the following:
Modifications:
DefaultClientRequestContext
into two:init()
method.ClientRequestContext.endpoint()
nullable, so that thedecorators can handle the case where endpoint selection has failed.
ClientRequestContext.endpointSelector()
.EndpointGroup.empty()
Result:
Endpoint
always refer to a host:port, which will greatlysimplify both users' code and ours in the future.
DefaultClientRequestContext.init()
) thatcan be used for
EventLoop
allocation and connection pooling in thefuture.
It currently has the following issues:WhenEndpointSelector.select()
raises an exception, the construction ofClientRequestContext
fails, which means you have no access to itsRequestLog
. We could makeClientRequestContext
available by deferringselect()
untilClientRequestContext
is constructed, but the decorators will still not be able to access to the request.The same problem will arise when we move the connection acquisition logic (connection pooling) to the beginning of request execution. The decorators will never see the connection failure.