通常,客户端可以通过以下方式取消 gRPC 调用:
(requestObserver as ClientCallStreamObserver<Request>)
.cancel("Cancelled", null)
Run Code Online (Sandbox Code Playgroud)
但是,它在Javadoc中显示:
CancellableContext withCancellation = Context.current().withCancellation();
// do stuff
withCancellation.cancel(t);
Run Code Online (Sandbox Code Playgroud)
哪一种是取消客户端调用并让服务器知道的“正确”方法?
编辑:
让事情变得更加混乱的是,还有ManagedChannel.shutdown*.
两者都是可接受且适当的。
clientCallStreamObserver.cancel()通常更容易,因为它的样板代码更少。一般来说应该是首选。然而,它不是线程安全的;就像在 StreamObserver 上正常发送一样。它还需要直接了解 RPC;您无法让更高级别的代码协调取消,因为它甚至可能不知道 RPC。
使用Context取消来实现线程安全取消和较少 RPC 感知的取消。上下文取消可用于类似于线程中断或 Future 取消的情况。并不是说CancellableContexts 应该被视为资源并且最终必须被取消以避免内存泄漏。(context.cancel(null)当上下文达到其“正常”生命周期时可以使用。)