core: exclude client and hedging cancellations from callcounters for outlier-detection - #12923
core: exclude client and hedging cancellations from callcounters for outlier-detection#12923AgraVator wants to merge 16 commits into
Conversation
…ications with transport stream closure
This reverts commit f9dd0fb.
…portTest" This reverts commit 5e558a5.
| Status status, RpcProgress rpcProgress, Metadata trailers) { | ||
| if (!listenerClosed) { | ||
| listenerClosed = true; | ||
| if (status.getCode() == Status.Code.CANCELLED) { |
There was a problem hiding this comment.
This method is for transport callback for stream closure and it is too late at this point to make a distinction whether the cancellation is app/retriable stream initiated or from the remote endpoint. This should instead be done in method cancel that sets this.cancelled = true; and that call only happens for app/retriable stream initiated cancellation, and not for remote server initiated cancellations, and happens before the transport stream is closed.
There was a problem hiding this comment.
In addition, we would need the guard in AbstractClientStream.cancel against late cancellations:
@Override
public final void cancel(Status reason) {
Preconditions.checkArgument(!reason.isOk(), "Should not cancel with OK status");
if (cancelled || transportState().listenerClosed) { // <----- GUARD
return;
}
cancelled = true;
statsTraceCtx.clientCancelled(reason);
abstractClientStreamSink().cancel(reason);
}
There was a problem hiding this comment.
Placing statsTraceCtx.clientCancelled(reason) inside cancel() on the calling thread (app thread or deadline timer thread) could result in a race condition. Had it like that in the initial commits but then eric suggested to use transportReadyStatus() instead.
… detection call counter
a573991 to
bf90eb5
Compare
| Status status, RpcProgress rpcProgress, Metadata trailers, boolean stopDelivery) { | ||
| if (!listenerClosed) { | ||
| listenerClosed = true; | ||
| if (stopDelivery) { |
There was a problem hiding this comment.
Using stopDelivery == true as the only indicator of a client-initiated cancellation is flawed because its meaning is context-dependent:
- Client Cancels (App / Hedging): Passes stopDelivery = true.
- Client Timeouts (DEADLINE_EXCEEDED): Passes stopDelivery = true.
- Transport Forceful Shutdown (UNAVAILABLE): Passes stopDelivery = true.
- Abrupt Network Drop (UNAVAILABLE): Passes stopDelivery = false.
- Server Sends Reset (CANCEL or INTERNAL): Passes stopDelivery = false.
(3) is a problem. In Netty transport for example, NettyClientHandler.forcefulClose explicitly sets stopDelivery = true (passing Status.UNAVAILABLE or similar).
Change this to:
// We must ensure the status code actually reflects a client-initiated action!
if (stopDelivery && (status.getCode() == Status.Code.CANCELLED ||
status.getCode() == Status.Code.DEADLINE_EXCEEDED)) {
statsTraceCtx.clientCancelled(status);
}
There was a problem hiding this comment.
No, we definitely shouldn't be doing any logic here based on the status code.
What is wrong with "Transport Forceful Shutdown'? That is defined as cancelling all streams, so it should behave the same as call.cancel().
I can believe we may need to change some cases to stop using stopDelivery=true; I bet there are/were some cases where it previously didn't matter what the value was. I think we can rename stopDelivery to cancelled, as that's the only time we should be discarding data that we've received.
There was a problem hiding this comment.
I wanted to count transport forceful shutdown in response to network drop as failure because it is not client app initiated although it might be client network stack initiated. Envoy does count connection drops as failures (LocalOriginConnectFailed) without any HTTP status code received from the remote peer.
| Status status, RpcProgress rpcProgress, Metadata trailers, boolean stopDelivery) { | ||
| if (!listenerClosed) { | ||
| listenerClosed = true; | ||
| if (stopDelivery) { |
There was a problem hiding this comment.
No, we definitely shouldn't be doing any logic here based on the status code.
What is wrong with "Transport Forceful Shutdown'? That is defined as cancelling all streams, so it should behave the same as call.cancel().
I can believe we may need to change some cases to stop using stopDelivery=true; I bet there are/were some cases where it previously didn't matter what the value was. I think we can rename stopDelivery to cancelled, as that's the only time we should be discarding data that we've received.
…s and add binder cancel test
fixes #12834