Skip to content

Commit 48ca452

Browse files
ramaraochavalizpencer
authored andcommitted
core: change serverimpl,servercallimpl's internalclose to cancel stream (#4038)
The HTTP/2 error code will be INTERNAL_ERROR for all cancel statuses, except for DEADLINE_EXCEEDED and CANCELLED, which are mapped to CANCELLED.
1 parent 887217e commit 48ca452

File tree

6 files changed

+26
-17
lines changed

6 files changed

+26
-17
lines changed

core/src/main/java/io/grpc/internal/ServerCallImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.grpc.ServerCall;
3838
import io.grpc.Status;
3939
import java.io.InputStream;
40+
import java.util.logging.Level;
4041
import java.util.logging.Logger;
4142

4243
final class ServerCallImpl<ReqT, RespT> extends ServerCall<ReqT, RespT> {
@@ -205,7 +206,8 @@ public MethodDescriptor<ReqT, RespT> getMethodDescriptor() {
205206
* on.
206207
*/
207208
private void internalClose(Status internalError) {
208-
stream.close(internalError, new Metadata());
209+
log.log(Level.WARNING, "Cancelling the stream with status {0}", new Object[] {internalError});
210+
stream.cancel(internalError);
209211
}
210212

211213
/**

core/src/main/java/io/grpc/internal/ServerImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,8 +629,7 @@ void setListener(ServerStreamListener listener) {
629629
* Like {@link ServerCall#close(Status, Metadata)}, but thread-safe for internal use.
630630
*/
631631
private void internalClose() {
632-
// TODO(ejona86): this is not thread-safe :)
633-
stream.close(Status.UNKNOWN, new Metadata());
632+
stream.cancel(Status.INTERNAL);
634633
}
635634

636635
@Override

core/src/test/java/io/grpc/internal/ServerCallImplTest.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,9 @@ private void sendMessage_serverSendsOne_closeOnSecondCall(
192192
verify(stream, times(1)).writeMessage(any(InputStream.class));
193193
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
194194
ArgumentCaptor<Metadata> metadataCaptor = ArgumentCaptor.forClass(Metadata.class);
195-
verify(stream, times(1)).close(statusCaptor.capture(), metadataCaptor.capture());
195+
verify(stream, times(1)).cancel(statusCaptor.capture());
196196
assertEquals(Status.Code.INTERNAL, statusCaptor.getValue().getCode());
197197
assertEquals(ServerCallImpl.TOO_MANY_RESPONSES, statusCaptor.getValue().getDescription());
198-
assertTrue(metadataCaptor.getValue().keys().isEmpty());
199198
}
200199

201200
@Test
@@ -221,7 +220,7 @@ private void sendMessage_serverSendsOne_closeOnSecondCall_appRunToCompletion(
221220
serverCall.sendMessage(1L);
222221
serverCall.sendMessage(1L);
223222
verify(stream, times(1)).writeMessage(any(InputStream.class));
224-
verify(stream, times(1)).close(any(Status.class), any(Metadata.class));
223+
verify(stream, times(1)).cancel(any(Status.class));
225224

226225
// App runs to completion but everything is ignored
227226
serverCall.sendMessage(1L);
@@ -255,11 +254,9 @@ private void serverSendsOne_okFailsOnMissingResponse(
255254
CompressorRegistry.getDefaultInstance());
256255
serverCall.close(Status.OK, new Metadata());
257256
ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
258-
ArgumentCaptor<Metadata> metadataCaptor = ArgumentCaptor.forClass(Metadata.class);
259-
verify(stream, times(1)).close(statusCaptor.capture(), metadataCaptor.capture());
257+
verify(stream, times(1)).cancel(statusCaptor.capture());
260258
assertEquals(Status.Code.INTERNAL, statusCaptor.getValue().getCode());
261259
assertEquals(ServerCallImpl.MISSING_RESPONSE, statusCaptor.getValue().getDescription());
262-
assertTrue(metadataCaptor.getValue().keys().isEmpty());
263260
}
264261

265262
@Test

core/src/test/java/io/grpc/internal/ServerImplTest.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,7 @@ public void messageRead_errorCancelsCall() throws Exception {
11081108
fail("Expected exception");
11091109
} catch (TestError t) {
11101110
assertSame(expectedT, t);
1111-
ensureServerStateNotLeaked();
1111+
ensureServerStateIsCancelled();
11121112
}
11131113
}
11141114

@@ -1133,7 +1133,7 @@ public void messageRead_runtimeExceptionCancelsCall() throws Exception {
11331133
fail("Expected exception");
11341134
} catch (RuntimeException t) {
11351135
assertSame(expectedT, t);
1136-
ensureServerStateNotLeaked();
1136+
ensureServerStateIsCancelled();
11371137
}
11381138
}
11391139

@@ -1156,7 +1156,7 @@ public void halfClosed_errorCancelsCall() {
11561156
fail("Expected exception");
11571157
} catch (TestError t) {
11581158
assertSame(expectedT, t);
1159-
ensureServerStateNotLeaked();
1159+
ensureServerStateIsCancelled();
11601160
}
11611161
}
11621162

@@ -1179,7 +1179,7 @@ public void halfClosed_runtimeExceptionCancelsCall() {
11791179
fail("Expected exception");
11801180
} catch (RuntimeException t) {
11811181
assertSame(expectedT, t);
1182-
ensureServerStateNotLeaked();
1182+
ensureServerStateIsCancelled();
11831183
}
11841184
}
11851185

@@ -1202,7 +1202,7 @@ public void onReady_errorCancelsCall() {
12021202
fail("Expected exception");
12031203
} catch (TestError t) {
12041204
assertSame(expectedT, t);
1205-
ensureServerStateNotLeaked();
1205+
ensureServerStateIsCancelled();
12061206
}
12071207
}
12081208

@@ -1225,7 +1225,7 @@ public void onReady_runtimeExceptionCancelsCall() {
12251225
fail("Expected exception");
12261226
} catch (RuntimeException t) {
12271227
assertSame(expectedT, t);
1228-
ensureServerStateNotLeaked();
1228+
ensureServerStateIsCancelled();
12291229
}
12301230
}
12311231

@@ -1396,6 +1396,12 @@ private void ensureServerStateNotLeaked() {
13961396
assertTrue(metadataCaptor.getValue().keys().isEmpty());
13971397
}
13981398

1399+
private void ensureServerStateIsCancelled() {
1400+
verify(stream).cancel(statusCaptor.capture());
1401+
assertEquals(Status.INTERNAL, statusCaptor.getValue());
1402+
assertNull(statusCaptor.getValue().getCause());
1403+
}
1404+
13991405
private static class SimpleServer implements io.grpc.internal.InternalServer {
14001406
ServerListener listener;
14011407

interop-testing/src/test/java/io/grpc/testing/integration/MoreInProcessTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ public void onCompleted() {
247247
.onNext(StreamingInputCallRequest.getDefaultInstance());
248248

249249
assertTrue(finishLatch.await(900, TimeUnit.MILLISECONDS));
250-
assertEquals(Status.UNKNOWN, Status.fromThrowable(throwableRef.get()));
250+
assertEquals(Status.CANCELLED.getCode(), Status.fromThrowable(throwableRef.get()).getCode());
251251
assertNull(responseRef.get());
252252
}
253253
}

netty/src/main/java/io/grpc/netty/NettyServerHandler.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,8 +654,13 @@ private void cancelStream(ChannelHandlerContext ctx, CancelServerStreamCommand c
654654
ChannelPromise promise) {
655655
// Notify the listener if we haven't already.
656656
cmd.stream().transportReportStatus(cmd.reason());
657+
Http2Error http2Error = Http2Error.INTERNAL_ERROR;
658+
if (Status.DEADLINE_EXCEEDED.getCode().equals(cmd.reason().getCode()) || Status.CANCELLED
659+
.getCode().equals(cmd.reason().getCode())) {
660+
http2Error = Http2Error.CANCEL;
661+
}
657662
// Terminate the stream.
658-
encoder().writeRstStream(ctx, cmd.stream().id(), Http2Error.CANCEL.code(), promise);
663+
encoder().writeRstStream(ctx, cmd.stream().id(), http2Error.code(), promise);
659664
}
660665

661666
private void forcefulClose(final ChannelHandlerContext ctx, final ForcefulCloseCommand msg,

0 commit comments

Comments
 (0)