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

Fix a bug where an IllegalStateException is raised on a non-ready EndpointGroup #3338

Merged
merged 4 commits into from Feb 10, 2021

Conversation

ikhoon
Copy link
Contributor

@ikhoon ikhoon commented Feb 9, 2021

…EndpointGroup`

Motivation:

If an EndpointGroup is not initialized with initial values,
a gRPC client will raise an IllegalStateException with the following message:

io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed@3830513a
java.lang.IllegalStateException: Should call init(endpoint) before invoking this method.

A WebClient waits a connection timeout for the EndpointGroup to have at least one Endpoint by @trustin's work (#2837)
However, a gRPC client does not wait for the EndPointGroup and start a gRPC request immediately.

Modifications:

  • Add DefaultClientRequestContext.whenIntialized() which completes
    when a ctx is initialized with an EndpointGroup.
  • Defer a gRPC call until a whenIntialized() is completed.

Result:

…EndpointGroup`

Motivation:

If an `EndpointGroup` is not initialized with initial values,
a gRPC client will raise an `IllegalStateException` with the following message:
```java
io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1HalfClosed@3830513a
java.lang.IllegalStateException: Should call init(endpoint) before invoking this method.
```

A `WebClient` waits a connection timeout for the `EndpointGroup` to have at least one Endpoint.
However, a gRPC client does not wait for the `EndPointGroup` and start a gRPC request immediately.

Modifications:

- Add `DefaultClientRequestContext.whenIntialized()` which completes
  when a `ctx` is initialized with an `EndpointGroup`.
- Defer a gRPC call until a `whenIntialized()` is completed.

Result:

- You no longer see an `IllegalStateException` if a gRPC call is sent to a non-ready `EndpointGroup`
- Fixes line#3332
@ikhoon ikhoon added the defect label Feb 9, 2021
@ikhoon ikhoon added this to the 1.5.0 milestone Feb 9, 2021
@codecov
Copy link

codecov bot commented Feb 9, 2021

Codecov Report

Merging #3338 (b058e82) into master (79971e1) will decrease coverage by 0.04%.
The diff coverage is 68.42%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #3338      +/-   ##
============================================
- Coverage     74.17%   74.13%   -0.05%     
- Complexity    13255    13269      +14     
============================================
  Files          1158     1158              
  Lines         50536    50597      +61     
  Branches       6469     6485      +16     
============================================
+ Hits          37483    37508      +25     
- Misses         9743     9774      +31     
- Partials       3310     3315       +5     
Impacted Files Coverage Δ Complexity Δ
...armeria/internal/common/CancellationScheduler.java 76.05% <ø> (+0.31%) 81.00 <0.00> (ø)
...rp/armeria/client/DefaultClientRequestContext.java 89.45% <67.85%> (-2.40%) 92.00 <7.00> (+6.00) ⬇️
...rmeria/internal/client/grpc/ArmeriaClientCall.java 79.32% <68.75%> (-3.51%) 67.00 <20.00> (+13.00) ⬇️
...om/linecorp/armeria/client/HttpSessionHandler.java 72.57% <0.00%> (-8.58%) 48.00% <0.00%> (-4.00%)
.../armeria/client/endpoint/dns/DnsEndpointGroup.java 78.12% <0.00%> (-3.13%) 13.00% <0.00%> (-2.00%)
...meria/client/DefaultDnsQueryLifecycleObserver.java 73.23% <0.00%> (-2.82%) 11.00% <0.00%> (-1.00%)
...com/linecorp/armeria/server/saml/SamlEndpoint.java 62.50% <0.00%> (-2.50%) 10.00% <0.00%> (-1.00%)
...eria/internal/common/DefaultSplitHttpResponse.java 77.38% <0.00%> (-2.39%) 14.00% <0.00%> (ø%)
...rmeria/common/stream/ConcatArrayStreamMessage.java 63.73% <0.00%> (-2.20%) 6.00% <0.00%> (ø%)
.../com/linecorp/armeria/server/docs/ServiceInfo.java 78.94% <0.00%> (-1.76%) 20.00% <0.00%> (-1.00%)
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 79971e1...6a23bf5. Read the comment docs.

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.

Thanks!

}

private void execute(Runnable task) {
if (endpointInitialized || ctx.whenInitialized().isDone()) {
Copy link
Member

Choose a reason for hiding this comment

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

We could use assert for this condition if we always guard this method with needsDirectInvocation().

Copy link
Contributor Author

@ikhoon ikhoon Feb 10, 2021

Choose a reason for hiding this comment

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

endpointInitialized could be either true, false here.
Because endpointInitialized || ctx.whenInitialized().isDone() and ctx.eventLoop().inEventLoop() are connected by && condition in needsDirectInvocation().

Copy link
Member

Choose a reason for hiding this comment

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

Ah, indeed. Sorry for a bad comment 😅

@trustin trustin changed the title Fix a bug where an IllegalStateException is raised on a non-ready `… Fix a bug where an IllegalStateException is raised on a non-ready EndpointGroup Feb 10, 2021
@trustin trustin merged commit d2d6207 into line:master Feb 10, 2021
@trustin
Copy link
Member

trustin commented Feb 10, 2021

Thanks, @ikhoon!

@ikhoon ikhoon deleted the empty-endpoint branch February 10, 2021 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IllegalStateException when making a gRPC call to a non-ready EndpointGroup.
3 participants