2016-06-09 4 views
0

вчера я играл arround с RPC в ходу и имел поведение, которое я не мог понять.RPC в Go имеет своего рода кеш?

Я написал простой сервер RPC, который работает в виртуальной машине, прослушивает подключения и служит для вычисления метода фибоначчи одним методом. Клиент RPC на локальном компьютере запрашивает сервер каждую секунду для фибоначчи (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

 Смежные вопросы

  • Нет связанных вопросов^_^