我已经在Android应用程序中设置了双向流构造,目前正在使用该机制发送大文件块。我遇到的问题是我的应用程序将收到文件请求消息,然后我将以潜在的数百MB的响应GRPC消息响应,这经常导致OOM。伪代码:
public class Myclass implements StreamObserver<CameraRequest>, Closeable {
...
public void onNext(Request req) {
for (Chunk chunk : getChunks(req))
this.requestObserver.onNext(builder.setChunk(chunk).build());
}
...
}
是否有一些不错的方法可以根据线路上实际放置的内容(以及可释放的相应内存)来限制对onNext的未完成呼叫的数量? IE仅允许对onNext进行10次调用,然后阻止后续调用,直到基础协议栈成功发送了先前调用的数据?我可以用我的有线协议TCP样式实现完整的e2e确认窗口,但希望其他人正在使用一种更简单的内置技术。
谢谢!
答案 0 :(得分:0)
将requestObserver
投射到ClientCallStreamObserver
。然后,您可以致电clientCallStreamObserver.isReady()
来检查是否应该停止发送。
然后,当RPC准备接收更多消息时,您将需要通知以恢复发送。为此,实现ClientResponseObserver
并在clientCallStreamObserver.setOnReadyHandler(Runnable)
中调用beforeStart()
。
将所有内容放在一起,可以得到类似的东西:
public class MyClass implements
ClientResponseObserver<CameraRequest,CameraResponse> {
private ClientCallStreamObserver<CameraRequest> requestObserver;
private Iterable<Chunk> chunks;
public void beforeStart(ClientCallStreamObserver<CameraRequest> requestObserver) {
this.requestObserver = requestObserver;
requestObserver.setOnReadyHandler(MyClass::drain);
}
public void onNext(CameraRequest req) {
// I don't know if this assert valid for your protocol
assert chunks == null || !chunks.hasNext();
chunks = getChunks(req);
drain();
}
public void drain() {
while (requestObserver.isReady() && chunks.hasNext()) {
Chunk chunk = chunks.next();
requestObserver.onNext(builder.setChunk(chunk).build());
}
}
...
}
答案 1 :(得分:0)
您可以查看流控制示例here。