Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 746ecca

Browse filesBrowse files
committed
Fix inbound flow control for Calls.blockingServerStreamingCall
asyncServerStreamingCall provides the initial request(1). Fixes grpc#93
1 parent 161ac95 commit 746ecca
Copy full SHA for 746ecca

1 file changed

+11-3Lines changed: 11 additions & 3 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎stub/src/main/java/io/grpc/stub/Calls.java‎

Copy file name to clipboardExpand all lines: stub/src/main/java/io/grpc/stub/Calls.java
+11-3Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,11 @@
4545

4646
import java.util.Iterator;
4747
import java.util.NoSuchElementException;
48+
import java.util.concurrent.BlockingQueue;
4849
import java.util.concurrent.CancellationException;
4950
import java.util.concurrent.ExecutionException;
5051
import java.util.concurrent.Future;
51-
import java.util.concurrent.LinkedBlockingQueue;
52+
import java.util.concurrent.ArrayBlockingQueue;
5253
import java.util.concurrent.TimeUnit;
5354

5455
/**
@@ -148,7 +149,7 @@ public static <ReqT, RespT> void asyncUnaryCall(
148149
// TODO(lryan): Not clear if we want to use this idiom for 'simple' stubs.
149150
public static <ReqT, RespT> Iterator<RespT> blockingServerStreamingCall(
150151
Call<ReqT, RespT> call, ReqT param) {
151-
BlockingResponseStream<RespT> result = new BlockingResponseStream<RespT>();
152+
BlockingResponseStream<RespT> result = new BlockingResponseStream<RespT>(call);
152153
asyncServerStreamingCall(call, param, result.listener());
153154
return result;
154155
}
@@ -331,11 +332,17 @@ public void onClose(Status status, Metadata.Trailers trailers) {
331332
*/
332333
// TODO(ejona): determine how to allow Call.cancel() in case of application error.
333334
private static class BlockingResponseStream<T> implements Iterator<T> {
334-
private final LinkedBlockingQueue<Object> buffer = new LinkedBlockingQueue<Object>();
335+
// Due to flow control, only needs to hold up to 2 items: 1 for value, 1 for close.
336+
private final BlockingQueue<Object> buffer = new ArrayBlockingQueue<Object>(2);
335337
private final Call.Listener<T> listener = new QueuingListener();
338+
private final Call<?, T> call;
336339
// Only accessed when iterating.
337340
private Object last;
338341

342+
private BlockingResponseStream(Call<?, T> call) {
343+
this.call = call;
344+
}
345+
339346
Call.Listener<T> listener() {
340347
return listener;
341348
}
@@ -362,6 +369,7 @@ public T next() {
362369
throw new NoSuchElementException();
363370
}
364371
try {
372+
call.request(1);
365373
@SuppressWarnings("unchecked")
366374
T tmp = (T) last;
367375
return tmp;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.