dongmou3615 2016-06-09 08:34
浏览 65
已采纳

Go中的RPC是否具有某种缓存?

yesterday I played arround with RPC in go and had a behaviour I couldn't understand.

I wrote a simple RPC server, which runs in a VM, listens for connections and serves a single method for fibonacci calculation. A RPC client on the local machine asks the server every second for fibonacci(n), where n is (currentSecond*fixedMultiplicator), so i can produce at least slightly different loads.

So, in a for loop, the client will request 60 different values in 60 seconds and then start over. The RPC dial is outside this loop, so the connection is somewhat persistent.

When I kill the server, lets say, after 10 seconds, the client will throw an error because it can't send anything to the now missing server. So far, works as planned.

Now what made me think: When I kill the server after 61 seconds, the client keeps printing out the correct results for ever request, although the server is missing and could not answer a request. I even shut down the VM of the server, so the server IP isn't even in the network any more. While being kind of interesting, this behavior could be harmful for a real application (depending on what you are developing).

Any ideas?

// ############
// # 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)
    }()
}

Answer

After running the code on Linux and Windows, I noticed different results. On Linux, the reply will always be the appropriate zero value (in my case 0). On Windows on the other hand it the reply seems to be cached.

The way to go is @cnicutar's hint. Check error value after the RPC call and handle stuff accordingly. Never trust the reply blindly.

  • 写回答

1条回答 默认 最新

  • doushenmao9036 2016-06-09 08:54
    关注

    You don't check for errors in your code:

    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)
    }()
    

    That said, I think the behavior is peculiar and there might be more to this.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100