Use stream.cancel() instead of cancel() in ClientCallImpl

Using cancel() sets cancelCalled=true which causes methods like
sendMessage() to throw IllegalStateException. This results in spurious
exceptions that are impossible to avoid. The API was designed to only
throw IllegalStateException when the caller called methods in the wrong
order, which is not the case here.

Fixes #1531
This commit is contained in:
Eric Anderson 2016-03-24 10:41:04 -07:00
parent 65d3847d14
commit 3ead41141e
2 changed files with 6 additions and 12 deletions

View File

@ -108,7 +108,7 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
@Override
public void cancelled(Context context) {
cancel();
stream.cancel(Status.CANCELLED.withCause(context.cancellationCause()));
}
/**
@ -316,7 +316,7 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
InputStream messageIs = method.streamRequest(message);
stream.writeMessage(messageIs);
} catch (Throwable e) {
cancel(Status.CANCELLED.withCause(e).withDescription("Failed to stream message"));
stream.cancel(Status.CANCELLED.withCause(e).withDescription("Failed to stream message"));
return;
}
// For unary requests, we don't flush since we know that halfClose should be coming soon. This
@ -379,7 +379,7 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
observer.onHeaders(headers);
} catch (Throwable t) {
cancel(Status.CANCELLED.withCause(t).withDescription("Failed to read headers"));
stream.cancel(Status.CANCELLED.withCause(t).withDescription("Failed to read headers"));
return;
}
}
@ -402,7 +402,7 @@ final class ClientCallImpl<ReqT, RespT> extends ClientCall<ReqT, RespT>
message.close();
}
} catch (Throwable t) {
cancel(Status.CANCELLED.withCause(t).withDescription("Failed to read message."));
stream.cancel(Status.CANCELLED.withCause(t).withDescription("Failed to read message."));
return;
}
}

View File

@ -364,14 +364,8 @@ public class ClientCallImplTest {
cancellableContext.cancel(new Throwable());
verify(stream, times(1)).cancel(Status.CANCELLED);
try {
call.sendMessage(null);
fail("Call has been cancelled");
} catch (IllegalStateException ise) {
// expected
}
verify(stream, times(1)).cancel(statusCaptor.capture());
assertEquals(Status.Code.CANCELLED, statusCaptor.getValue().getCode());
}
@Test