mirror of https://github.com/grpc/grpc-java.git
Allow application to pass cancellation details.
Resolves #1221 Add ClientCall.cancel(String, Throwable) and deprecate ClientCall.cancel(). Will delete cancel() after all known third-party overriders have switched to overriding the new one.
This commit is contained in:
parent
38a91f83e1
commit
16e168951a
|
@ -182,12 +182,12 @@ public class ClientAuthInterceptorTests {
|
|||
interceptedCall = interceptor.interceptCall(descriptor, CallOptions.DEFAULT, channel);
|
||||
interceptedCall.start(listener, new Metadata());
|
||||
verify(credentials).getRequestMetadata(URI.create("https://example.com/a.service"));
|
||||
interceptedCall.cancel();
|
||||
interceptedCall.cancel("Cancel for test", null);
|
||||
|
||||
doReturn("example.com:123").when(channel).authority();
|
||||
interceptedCall = interceptor.interceptCall(descriptor, CallOptions.DEFAULT, channel);
|
||||
interceptedCall.start(listener, new Metadata());
|
||||
verify(credentials).getRequestMetadata(URI.create("https://example.com:123/a.service"));
|
||||
interceptedCall.cancel();
|
||||
interceptedCall.cancel("Cancel for test", null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,7 +515,7 @@ class LoadClient {
|
|||
call.sendMessage(genericRequest.slice());
|
||||
now = System.nanoTime();
|
||||
if (shutdown) {
|
||||
call.cancel();
|
||||
call.cancel("Shutting down", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An instance of a call to to a remote method. A call will send zero or more
|
||||
* request messages to the server and receive zero or more response messages back.
|
||||
|
@ -156,16 +158,35 @@ public abstract class ClientCall<ReqT, RespT> {
|
|||
*/
|
||||
public abstract void request(int numMessages);
|
||||
|
||||
/**
|
||||
* Equivalent as {@link #cancel(String, Throwable)} without passing any useful information.
|
||||
*
|
||||
* @deprecated Use or override {@link #cancel(String, Throwable)} instead. See
|
||||
* https://github.com/grpc/grpc-java/issues/1221
|
||||
*/
|
||||
@Deprecated
|
||||
public void cancel() {
|
||||
cancel("Cancelled by ClientCall.cancel()", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent any further processing for this {@code ClientCall}. No further messages may be sent or
|
||||
* will be received. The server is informed of cancellations, but may not stop processing the
|
||||
* call. Cancellation is permitted if previously {@link #halfClose}d. Cancelling an already {@code
|
||||
* cancel()}ed {@code ClientCall} has no effect.
|
||||
*
|
||||
*
|
||||
* <p>No other methods on this class can be called after this method has been called.
|
||||
*
|
||||
* <p>It is recommended that at least one of the arguments to be non-{@code null}, to provide
|
||||
* useful debug information. Both argument being null may log warnings and result in suboptimal
|
||||
* performance. Also note that the provided information will not be sent to the server.
|
||||
*
|
||||
* @param message if not {@code null}, will appear as the description of the CANCELLED status
|
||||
* @param cause if not {@code null}, will appear as the cause of the CANCELLED status
|
||||
*/
|
||||
public abstract void cancel();
|
||||
public void cancel(@Nullable String message, @Nullable Throwable cause) {
|
||||
throw new UnsupportedOperationException(getClass() + " should implement this method");
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the call for request message sending. Incoming response messages are unaffected. This
|
||||
|
|
|
@ -134,7 +134,7 @@ public class ClientInterceptors {
|
|||
public void request(int numMessages) {}
|
||||
|
||||
@Override
|
||||
public void cancel() {}
|
||||
public void cancel(String message, Throwable cause) {}
|
||||
|
||||
@Override
|
||||
public void halfClose() {}
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A {@link ClientCall} which forwards all of it's methods to another {@link ClientCall}.
|
||||
*/
|
||||
|
@ -50,11 +52,17 @@ public abstract class ForwardingClientCall<ReqT, RespT> extends ClientCall<ReqT,
|
|||
delegate().request(numMessages);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void cancel() {
|
||||
delegate().cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel(@Nullable String message, @Nullable Throwable cause) {
|
||||
delegate().cancel(message, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void halfClose() {
|
||||
delegate().halfClose();
|
||||
|
|
|
@ -304,7 +304,7 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
public void cancel(@Nullable String message, @Nullable Throwable cause) {
|
||||
if (cancelCalled) {
|
||||
return;
|
||||
}
|
||||
|
@ -313,8 +313,20 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
|
|||
// Cancel is called in exception handling cases, so it may be the case that the
|
||||
// stream was never successfully created.
|
||||
if (stream != null) {
|
||||
stream.cancel(Status.CANCELLED.withCause(
|
||||
new CancellationException("Client requested cancellation")));
|
||||
Status status = Status.CANCELLED;
|
||||
if (message != null) {
|
||||
status = status.withDescription(message);
|
||||
}
|
||||
if (cause != null) {
|
||||
status = status.withCause(cause);
|
||||
}
|
||||
if (message == null && cause == null) {
|
||||
// TODO(zhangkun83): log a warning with this exception once cancel() has been deleted from
|
||||
// ClientCall.
|
||||
status = status.withCause(
|
||||
new CancellationException("Client called cancel() without any detail"));
|
||||
}
|
||||
stream.cancel(status);
|
||||
}
|
||||
} finally {
|
||||
if (context != null) {
|
||||
|
|
|
@ -399,7 +399,7 @@ public class ClientInterceptorsTest {
|
|||
// Make sure nothing bad happens after the exception.
|
||||
ClientCall<?, ?> noop = ((CheckedForwardingClientCall<?, ?>)interceptedCall).delegate();
|
||||
// Should not throw, even on bad input
|
||||
noop.cancel();
|
||||
noop.cancel("Cancel for test", null);
|
||||
noop.start(null, null);
|
||||
noop.request(-1);
|
||||
noop.halfClose();
|
||||
|
|
|
@ -289,7 +289,7 @@ public class ManagedChannelImplTest {
|
|||
ClientStream mockStream = mock(ClientStream.class);
|
||||
when(mockTransport.newStream(same(method), same(headers))).thenReturn(mockStream);
|
||||
call.start(mockCallListener, headers);
|
||||
call.cancel();
|
||||
call.cancel("Cancel for test", null);
|
||||
|
||||
verify(mockTransport, timeout(1000)).start(transportListenerCaptor.capture());
|
||||
final ManagedClientTransport.Listener transportListener = transportListenerCaptor.getValue();
|
||||
|
|
|
@ -113,7 +113,7 @@ public class ClientCalls {
|
|||
try {
|
||||
return getUnchecked(futureUnaryCall(call, param));
|
||||
} catch (Throwable t) {
|
||||
call.cancel();
|
||||
call.cancel(null, t);
|
||||
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ public class ClientCalls {
|
|||
}
|
||||
return getUnchecked(responseFuture);
|
||||
} catch (Throwable t) {
|
||||
call.cancel();
|
||||
call.cancel(null, t);
|
||||
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ public class ClientCalls {
|
|||
call.sendMessage(param);
|
||||
call.halfClose();
|
||||
} catch (Throwable t) {
|
||||
call.cancel();
|
||||
call.cancel(null, t);
|
||||
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
|
@ -265,8 +265,7 @@ public class ClientCalls {
|
|||
|
||||
@Override
|
||||
public void onError(Throwable t) {
|
||||
// TODO(ejona86): log?
|
||||
call.cancel();
|
||||
call.cancel("Cancelled by client with StreamObserver.onError()", t);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -368,7 +367,7 @@ public class ClientCalls {
|
|||
|
||||
@Override
|
||||
protected void interruptTask() {
|
||||
call.cancel();
|
||||
call.cancel("GrpcFuture was cancelled", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -101,7 +101,7 @@ public class ClientCallsTest {
|
|||
verify(call).start(listenerCaptor.capture(), any(Metadata.class));
|
||||
ClientCall.Listener<String> listener = listenerCaptor.getValue();
|
||||
future.cancel(true);
|
||||
verify(call).cancel();
|
||||
verify(call).cancel("GrpcFuture was cancelled", null);
|
||||
listener.onMessage("bar");
|
||||
listener.onClose(Status.OK, new Metadata());
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue