2017-05-03 46 views
0

我正在使用grpc-java項目中的StreamObserver類來設置一些雙向流。如何跟蹤發出/完成的請求而不使用其他狀態變量? (Java/Grpc)

當我運行我的程序時,我向服務器發出了未確定數量的請求,並且我只想在完成所有請求後調用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調試器中的對象,但沒有任何東西會彈出給我。

回答

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,則會知道所有請求都已完成。

+0

是的,我直到運行時才知道我將發出多少請求。你可以把它看作是unix「tree」命令。如果某個目錄是某個目錄,那麼我將對服務器執行「ls」操作,如果某個文件是某個文件,那麼我將打印出來。但我不知道目錄結構。因此,直到運行時,我對服務器所做的「ls」命令的數量都是未知的。 – Zack

+0

如果是這種情況,那麼你將不得不跟蹤未完成的RPC數量。並不是每個人都需要這些功能,所以我們將它放在API之外,以便讓這些人更快。有一個額外的計數器來跟蹤仍然預期的響應數量似乎並不是那麼糟糕。 –

相關問題