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.