我有一个用gRPC编写的C++服务器和一个用Java编写的客户机。使用阻塞存根一切都很好。然后我决定将其中一个调用更改为异步调用,因此我在我的客户机中创建了一个额外的存根,这个存根是用newStub(通道)创建的,而不是newBlockingStub(通道)。我没有在服务器端做任何更改。这是一个简单的一元RPC调用。
所以我改变了
Empty response = blockingStub.callMethod(request);
至
asyncStub.callMethod(request, new StreamObserver<Empty>() {
@Override
public void onNext(Empty response) {
logInfo("asyncStub.callMethod.onNext");
}
@Override
public void onError(Throwable throwable) {
logError("asyncStub.callMethod.onError " + throwable.getMessage());
}
@Override
public void onCompleted() {
logInfo("asyncStub.callMethod.onCompleted");
}
});
从那时起,当我使用这个RPC (大部分时间)时,onError就会被调用,它给出的错误是“取消: io.grpc.Context被取消而没有错误”。在从RPC调用中进行RPC调用时,我读过关于分叉上下文对象的文章,但这里不是这样的。而且,上下文似乎是一个服务器端对象,我不认为它与客户机有什么关系。这是一个服务器端错误传播回客户端吗?在服务器端,一切似乎都成功地完成了,所以我不知道为什么会发生这种情况。调用asyncStub.callMethod后插入1ms睡眠似乎可以解决这个问题,但却违背了目的。任何和所有的帮助,以了解这一点,将不胜感激。
一些注意事项:
服务器端的处理时间现在大约是1 microsecond
service EventHandler {
rpc callMethod(Msg) returns (Empty) {}
}
message Msg {
uint64 fieldA = 1;
int32 fieldB = 2;
string fieldC = 3;
string fieldD = 4;
}
message Empty {
}
发布于 2020-10-18 09:48:25
原来我错了。客户端也使用上下文对象。解决办法是做以下工作:
Context newContext = Context.current().fork();
Context origContext = newContext.attach();
try {
// Call async RPC here
} finally {
newContext.detach(origContext);
}
希望这能在未来帮助到其他人。
https://stackoverflow.com/questions/64355930
复制相似问题