2016-06-09 74 views
0

昨天我和RPC一起玩去了,有一種我無法理解的行爲。RPC中的RPC有某種緩存?

我寫了一個簡單的RPC服務器,運行在VM中,監聽連接併爲fibonacci計算提供單一方法。 本地機器上的RPC客戶端每秒詢問一次fibonacci(n),其中n是(currentSecond * fixedMultiplicator),所以我可以產生至少稍微不同的負載。

因此,在for循環中,客戶端將在60秒內請求60個不同的值,然後重新開始。 RPC撥號在此循環之外,因此連接有點持久。

當我殺死服務器時,可以說10秒後,客戶端會拋出一個錯誤,因爲它無法發送任何東西到現在丟失的服務器。到目前爲止,按計劃運作。

現在讓我想到的是:當我在61秒後終止服務器時,客戶端不斷輸出正確的結果以滿足不斷請求,儘管服務器丟失並且無法回答請求。我甚至關閉了服務器的虛擬機,所以服務器的IP甚至不在網絡中。 雖然有趣,但這種行爲可能對真實應用程序有害(取決於您正在開發的內容)。

任何想法?

// ############ 
// # RPC SERVER 

err := rpc.Register(service.Object) 
// errorcheck 

rpc.HandleHTTP() 
l, e := net.Listen("tcp", ":1301") 
// errorcheck 
go http.Serve(l, nil) 


// ############ 
// # RPC CLIENT 

client, err := rpc.DialHTTP("tcp", "192.168.2.111:1301") 
// errorcheck 

var divCall *rpc.Call 

for { 
    <-time.After(time.Duration(1 * time.Second)): 

    n := time.Now().Second() * 90000000 
    log.Debug("n=", n) 

    args := &services.FibonacciArgs{N: n} 
    var reply int 
    divCall = client.Go("Fibonacci.Calculate", args, &reply, nil) 

    go func() { 
     replyCall := <-divCall.Done 
     r := replyCall.Reply.(*int) 
     log.Debug("reply: ", r) 
    }() 
} 

回答

運行在Linux和Windows的代碼後,我發現不同的結果。 在Linux上,回覆將始終爲合適的零值(在我的情況下爲0)。另一方面,在Windows上,它的回覆似乎被緩存了。

要走的路是@ cnicutar的提示。檢查RPC調用後的錯誤值並相應地處理相應的東西。不要盲目信任回覆。

+0

我會對您調用RPC的客戶端代碼感興趣。 – cnicutar

+0

@cnicutar你去,剝離版http://pastebin.com/7uERKWER – tsdtsdtsd

+1

我添加了代碼的問題,它比pastebin更好:) – cnicutar

回答

1

你不檢查代碼中的錯誤:

divCall = client.Go("Fibonacci.Calculate", args, &reply, nil) 

go func() { 
    replyCall := <-divCall.Done 

    // -- Must check replyCall.Error here --. 

    r := replyCall.Reply.(*int) 
    log.Debug("reply: ", r) 
}() 

這麼說,我覺得行爲是特有的且可能存在更多的這個。

+0

謝謝,我將包括檢查!儘管如此,我猜'r:= replyCall.Reply。(* int)'仍然應該向我拋出一些東西,這與最後一個「連接的循環」不同。 – tsdtsdtsd

+0

@tsdtsdtsd檢查完成後,如果得到錯誤? – cnicutar

+0

您的提示指出我正確的方向,謝謝。我將在幾個問題上添加對我的問題的解釋。基本上它與操作系統有關 – tsdtsdtsd