diff options
author | ZHANG Dapeng <zdapeng@google.com> | 2018-06-28 12:52:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-28 12:52:17 -0700 |
commit | b244988572a0a671510f33b14816ff73241de479 (patch) | |
tree | 3b8d09beef4954f0be97bcfcb171a3342463253a /netty | |
parent | b88cf81a788e7705114977494fbfbe4f0494f2c7 (diff) | |
download | grpc-grpc-java-b244988572a0a671510f33b14816ff73241de479.tar.gz |
netty,okhttp: make rpc followed by racy GOAWAY transparent-retry-able
A new RPC starts with the following steps:
1. Pick a READY transport
2. the READY transport calls `transport.newStream()`
3. the new stream calls `stream.start()`
4. `stream.start()` invokes or enqueus `writeHeaders()` (or for GET request, noop)
A racy GOAWAY could happen between 3 and 4, and by the retry spec, the RPC should be transparent-retry-able in this case. For Netty and OkHttp transport implementation, before step 4, (even if step 1, 2, and 3 excluding 4 are made atomic,) the http2-stream for the RPC is not created, so the current transparent retry logic does not apply and need fix.
Of course, if step 1, 2, and 3 including 4 are made atomic, and not with GET, there will be no such problem.
Diffstat (limited to 'netty')
-rw-r--r-- | netty/src/main/java/io/grpc/netty/NettyClientHandler.java | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/netty/src/main/java/io/grpc/netty/NettyClientHandler.java b/netty/src/main/java/io/grpc/netty/NettyClientHandler.java index 92fdc06e7..b562e6237 100644 --- a/netty/src/main/java/io/grpc/netty/NettyClientHandler.java +++ b/netty/src/main/java/io/grpc/netty/NettyClientHandler.java @@ -459,7 +459,10 @@ class NettyClientHandler extends AbstractNettyHandler { private void createStream(CreateStreamCommand command, final ChannelPromise promise) throws Exception { if (lifecycleManager.getShutdownThrowable() != null) { - // The connection is going away, just terminate the stream now. + // The connection is going away (it is really the GOAWAY case), + // just terminate the stream now. + command.stream().transportReportStatus( + lifecycleManager.getShutdownStatus(), RpcProgress.REFUSED, true, new Metadata()); promise.setFailure(lifecycleManager.getShutdownThrowable()); return; } |