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 /okhttp | |
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 'okhttp')
-rw-r--r-- | okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java index 2828c7da2..6a3c0881e 100644 --- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java +++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpClientTransport.java @@ -351,15 +351,14 @@ class OkHttpClientTransport implements ConnectionClientTransport { @GuardedBy("lock") void streamReadyToStart(OkHttpClientStream clientStream) { - synchronized (lock) { - if (goAwayStatus != null) { - clientStream.transportState().transportReportStatus(goAwayStatus, true, new Metadata()); - } else if (streams.size() >= maxConcurrentStreams) { - pendingStreams.add(clientStream); - setInUse(); - } else { - startStream(clientStream); - } + if (goAwayStatus != null) { + clientStream.transportState().transportReportStatus( + goAwayStatus, RpcProgress.REFUSED, true, new Metadata()); + } else if (streams.size() >= maxConcurrentStreams) { + pendingStreams.add(clientStream); + setInUse(); + } else { + startStream(clientStream); } } |