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.

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

报告相同问题?

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站