2016-06-09 126 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