Skip to content

Commit

Permalink
Fixed bug where a null endpoint is returned (#5281)
Browse files Browse the repository at this point in the history
Motivation:

While fixing #5163, I made a bug that `EndpointSelector` returns a null endpoint due to a race condition between an EndpointGroup initialization event and `EndpointSelector.select()`.
```
Caused by:
com.linecorp.armeria.client.endpoint.EndpointSelectionTimeoutException: Failed to select within 3200 ms an endpoint from: HealthCheckedEndpointGroup{endpoints=[Endpoint{127.0.0.1:46843, weight=1000}], numEndpoints=1, candidates=[Endpoint{127.0.0.1:46843, weight=1000}], numCandidates=1, selectionStrategy=class com.linecorp.armeria.client.endpoint.WeightedRoundRobinStrategy, initialized=true, initialSelectionTimeoutMillis=15000, selectionTimeoutMillis=3200, contextGroupChain=[HealthCheckContextGroup{contexts={Endpoint{127.0.0.1:46843, weight=1000}=DefaultHealthCheckerContext{originalEndpoint=Endpoint{127.0.0.1:46843, weight=1000}, endpoint=Endpoint{127.0.0.1:46843, weight=1000}, initializationStarted=true, initialized=true, destroyed=false, refCnt=1}}, candidates=[Endpoint{127.0.0.1:46843, weight=1000}], initialized=true}]}
    at app//com.linecorp.armeria.client.endpoint.EndpointSelectionTimeoutException.get(EndpointSelectionTimeoutException.java:48)
    at app//com.linecorp.armeria.client.endpoint.AbstractEndpointSelector.lambda$select$0(AbstractEndpointSelector.java:105)
```

If a `ListeningFuture` is added to `pendingFutures` after an `EndpointGroup` update event is delivered, `listeningFuture` may not be completed within a selection timeout.

Modifications:

- Check if an `EndpointGroup` completes after adding `ListeningFuture` to `pendingFutures`.

Result:

You no longer see `EndpointSelectionTimeoutException` when selecting an `Endpoint` from an `EndpointGroup`.
  • Loading branch information
ikhoon authored Nov 8, 2023
1 parent ff9f2e0 commit f7dd931
Showing 1 changed file with 9 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,18 @@ public final CompletableFuture<Endpoint> select(ClientRequestContext ctx,
final ListeningFuture listeningFuture = new ListeningFuture(ctx, executor);
addPendingFuture(listeningFuture);

// The EndpointGroup have just been updated.
// The EndpointGroup have just been updated after adding ListeningFuture.
if (listeningFuture.isDone()) {
return listeningFuture;
}
if (endpointGroup.whenReady().isDone()) {
final Endpoint endpoint0 = selectNow(ctx);
if (endpoint0 != null) {
// The EndpointGroup have just been updated before adding ListeningFuture.
listeningFuture.complete(endpoint0);
return listeningFuture;
}
}

final long selectionTimeoutMillis = endpointGroup.selectionTimeoutMillis();
if (selectionTimeoutMillis == 0) {
Expand Down

0 comments on commit f7dd931

Please sign in to comment.