error-handling - 有人可以向我解释 gRPC StreamObserver.onError 的正确用法是什么吗?
问题描述
我正在尝试正确处理 gRPC 错误(Java、Spring-boot 应用程序)。
基本上,我也需要将错误详细信息从 gRPC 服务器传输到客户端,但我发现很难理解StreamObserver.onError();
方法文档说:
“从流中接收到一个终止错误。只能调用一次,如果被调用,它必须是最后一个调用的方法。特别是如果 onError 的实现抛出异常,则不允许进一步调用任何方法。”
这个“不允许再打电话”是什么意思?根据文档,在我维护的应用程序中,他们调用其他 gRPC 方法并且他们得到java.lang.IllegalStateException: call already closed
了很好的方法。
我想知道 - 我(开发人员)是否应该在收到错误后终止当前的 java 方法(使用 gRPC 调用)?例如抛出异常以停止执行。或者预计 gRPC 将终止执行..(类似于从 gRPC 抛出异常)
基本上我该如何正确使用onError()
,如果我调用它,我应该期待和处理什么?我需要解释它的用法和效果。
解决方案
涉及两个StreamObserver
实例。一种用于入站方向,即您实现并传递给 gRPC 库的StreamObserver
实例。这是包含如何处理响应的逻辑。另一个是outbound方向,即gRPC库调用RPC方法时返回给你的实例。这是您用来发送请求的。大多数时候,这两个是相互交互的(例如,在一个全双工的流式调用中,响应通常会调用 request的方法,这就是你实现乒乓行为的方式)。StreamObserver
StreamObserver
StreamObserver
StreamObserver
StreamObserver
StreamObserver
onNext()
“不允许进一步调用”意味着当调用 inbound的方法时onNext()
,您不应再调用onComplete()
和/或onError()
在出站方向上StreamObserver
调用,即使您的入站实现抛出异常也是如此。由于入站是异步调用的,因此它与包含's 实现的方法无关。StreamObserver
onError()
onError()
StreamObserver
StreamObserver
例如:
public class HelloWorld {
private final HelloWorldStub stub;
private StreamObserver<HelloRequest> requestObserver;
...
private void sendRequest(String message) {
requestObserver.onNext(HelloRequest.newBuilder.setMessage(message).build());
}
public void start() {
stub.helloWorld(new StreamObserver<HelloResponse> {
@Override
public void onNext(HelloResponse response) {
sendRequest("hello from client");
// Optionally you can call onCompleted() or onError() on
// the requestObserver to terminate the call.
}
@Override
public void onCompleted() {
// You should not call any method on requestObserver.
}
@Override
public void onError(Throwable error) {
// You should not call any method on requestObserver.
}
});
}
}
它与方法无关start()
。
该文档还提到您不应该做类似的事情
try {
requestObserver.onCompleted();
} catch(RuntimeException e) {
requestObserver.onError();
}
它主要用于用户自己的StreamObserver
实现。StreamObserver
由 gRPC 返回的永远不会抛出。
推荐阅读
- c++ - 模板函数中从 'const int*' 到 'int*' 的无效转换
- java - 如何从现有文件夹结构创建 Maven 项目?
- javascript - 我正在尝试向对象添加属性,但只有最后一个被附加
- python - 使用 pandas python 将使用 date_range 生成的索引添加到数据框
- c++ - Use template from dependent type
- angularjs - Scope 函数执行,但 HTML 从未更改
- keycloak - Keycloak:用户提交注册表后自动登录
- vhdl - 如何在 modelsim 中使用泛型数组类型?
- python - 将代码从 keras 移植到 tf.keras
- scala - 减少的参数太多 [Scala 中的 Flink 1.9]