如何在不使用其他状态变量的情况下跟踪发出/完成的请求? (爪哇/ GRPC)

时间:2017-05-03 14:39:36

标签: java stream request grpc

我正在使用grpc-java项目中的StreamObserver类来设置一些双向流。

当我运行程序时,我向服务器发出了一定数量的请求,我只想在完成所有请求后调用requestObserver上的onCompleted()。

目前,为了解决这个问题,我使用变量“inFlight”来跟踪已发出的请求,当响应回来时,我减少“inFlight”。所以,就像这样。

// issuing requests
while (haveRequests) {
    MessageRequest request = mkRequest();
    this.requestObserver.onNext(request);
    this.inFlight++; 
}


// response observer
StreamObserver<Message> responseObserver = new StreamObserver<Message> {

    @Override
    public void onNext(Message response) {
        if (--this.onFlight == 0) {
            this.requestObserver.onCompleted();
        }

        // work on message
    }

    // other methods

}

有点伪代码,但这种逻辑有效。但是,如果可能的话,我想摆脱“inFlight”变量。 StreamObserver类中是否有允许这种功能的东西,而不需要额外的变量来跟踪状态?可以告诉发出的请求数量和完成时间。

我已经尝试在intellij IDE调试器中检查对象,但没有任何东西弹出给我。

1 个答案:

答案 0 :(得分:0)

要回答您的直接问题,您只需从while循环调用onComplete即可。所有邮件都传递给onNext。在引擎盖下,gRPC将发送所谓的“半关闭”,表示它不会再发送任何消息,但它愿意接收它们。具体做法是:

// issuing requests
while (haveRequests) {
    MessageRequest request = mkRequest();
    this.requestObserver.onNext(request);
    this.inFlight++; 
}
requestObserver.onCompleted();

这可确保发送所有响应,并按照您发送的顺序发送。在服务器端,当它看到相应的onCompleted回调时,它可以通过在其观察者上调用onComplete来半连接其连接端。 (服务器端有两个观察者,一个用于从客户端接收信息,一个用于发送信息)。

回到客户端,您只需要等待服务器一半接近就知道所有消息都已收到并处理完毕。请注意,如果有任何错误,您将获得onError回调。

如果您知道您将在客户端提出多少请求,则可以考虑使用AtomicInteger,并在获得时调用decrementAndGet回复一个回应。如果返回值为0,您就会知道所有请求都已完成。