Does RPC have a timeout mechanism?
11,968
Solution 1
You can use channels to implement a timeout pattern:
import "time"
c := make(chan error, 1)
go func() { c <- client.Call("Service", args, &result) } ()
select {
case err := <-c:
// use err and result
case <-time.After(timeoutNanoseconds):
// call timed out
}
The select
will block until either client.Call
returns or timeoutNanoseconds
elapsed.
Solution 2
if you want to implement a timeout (to prevent a call from taking too long), then you'll want to change rpc.Dial for net.DialTimeout (notice they're separate packages: rpc vs net). Also be aware that the returned type isn't a client any more (as it is in the previous example); instead it is a 'connection'.
conn, err := net.DialTimeout("tcp", "localhost:8080", time.Minute)
if err != nil {
log.Fatal("dialing:", err)
}
client := rpc.NewClient(conn)
Author by
Aniruddh Chaturvedi
Updated on June 04, 2022Comments
-
Aniruddh Chaturvedi almost 2 years
If RPC does not have a timeout mechanism, how do I "kill" an RPC call if it is trying to call an RPC method of a server that is closed?
-
Rick-777 about 10 yearsThis is a good solution. But be aware that, when timeout happens, the goroutine will continue to run in the background, possibly holding on to OS resources.
-
Sebastian about 10 yearsThis would be correct if it would be an unbuffered channel. As I'm using a buffered channel with size 1 the go routine will not block.
-
valyala about 9 yearsSebastian, the goroutine may block forever in client.Call() if RPC server won't respond. This will result in goroutines' leak.
-
jnadro52 over 8 yearsAt least in Go 1.5, there is a client.Go method that is preferable
-
Navid about 4 yearsPlease be aware that in a large scale service time.After results in memory issues since it won't get collected by GC until it's triggered. Instead of time.Timer may be more desired because you can stop it manually.
-
yurenchen about 4 yearsas upstairs @valyala 's comment remind, if server not response, client.call will never return, the goroutine will leak.
-
Shindou-L about 2 yearsAccording my test, rpc.Client.Call method still not exit even I closed the underlying connection