【问题标题】:How can a gRPC server notice that the client has cancelled a server-side streaming call?gRPC 服务器如何注意到客户端取消了服务器端的流式调用?
【发布时间】:2019-07-02 10:59:16
【问题描述】:

我想使用 gRPC 让客户端订阅服务器生成的事件。我有一个这样声明的 RPC:

rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse);

返回的流是无限的。要“取消订阅”,客户端会取消 RPC(顺便说一句。有更清洁的方法吗?)。

我已经弄清楚客户如何取消通话:

Context.CancellableContext cancellableContext =
         Context.current().withCancellation();
cancellableContext.run(() -> {
   stub.subscribe(request, callback);
});
// do other stuff / wait for reason to unsubscribe
cancellableContext.cancel(new InterruptedException());

但是,服务器似乎没有注意到客户端已取消其调用。我正在使用虚拟服务器实现对此进行测试:

@Override
public void subscribe(SubscribeRequest request,
                      StreamObserver<SubscribeResponse> responseObserver) {
  // in real code, this will happen in a separate thread.
  while (!Thread.interrupted()) {
    responseObserver.onNext(SubscribeResponse.getDefaultInstance());
  }
}

服务器将愉快地继续将其消息发送到以太。服务器如何识别呼叫已被客户端取消,从而停止发送响应?

【问题讨论】:

    标签: grpc grpc-java


    【解决方案1】:

    我自己找到了答案。您将传递的StreamObserver 转换为订阅ServerCallStreamObserver,它公开了方法isCancelledsetOnCancelHandler

    scso = ((ServerCallStreamObserver<SubscribeResponse>) responseObserver);
    
    scso.setOnCancelHandler(handler);
    // or
    if (scso.isCancelled()) {
      // do whatever
    }
    

    对我来说,这引出了一个问题,为什么 subscribe 没有通过 ServerCallStreamObserver 开始。

    【讨论】:

    • 我们无法更改类型,因为这会破坏现有用户 :-( 。我们必须保留旧方法,这会带来其自身的混乱。注意 Context.addListener() 是另一种选择。使用 ServerCallStreamObserver,回调与其他回调同步(如 onNext/onCompleted)。使用 Context 将单独调用,您的实现需要担心线程安全。
    • @eric-anderson,很抱歉,每当我看到“以前的用户”争论时,我必须停止我正在做的任何事情,并呼吁公牛。是的,2016 年可能有 10 个人在 Google 之外使用 gRPC 会注意到一个类型是否被重命名,但是 2020 年有 10000 人使用 gRPC 呢?为什么他们会继续困惑?然后是版本控制;在世界末日到来之前,API 不必向后兼容。
    • @AbhijitSarkar 一些拥有复杂微服务网络、面临大量流量的组织(例如 Netflix)已经使用 gRPC 有一段时间了。我想他们会把 Eric 完全钉死在十字架上,如果他突然像那样改变 API ;-] 不过,我认为拥有 2 个版本的方法是一个更好的主意,而不是强迫人们在每个方法的开头执行一些奇怪的转换; -)
    • @morgwai 我确实说过“然后是版本控制”;这是软件维护人员在更改 API 之前唯一需要提出的论点。
    • @morgwai 以前的主要版本将进入维护模式,仅修复错误,首先是一两个次要版本,然后不再维护。这不是问题,根本不是软件问题;这是一个图书馆维护者想在多大程度上向后弯腰以取悦大公司的问题。
    猜你喜欢
    • 2017-09-20
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2019-11-12
    • 2018-04-12
    • 2020-09-09
    相关资源
    最近更新 更多