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)
Share:
11,968
Aniruddh Chaturvedi
Author by

Aniruddh Chaturvedi

Updated on June 04, 2022

Comments

  • Aniruddh Chaturvedi
    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
    Rick-777 about 10 years
    This 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
    Sebastian about 10 years
    This 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
    valyala about 9 years
    Sebastian, the goroutine may block forever in client.Call() if RPC server won't respond. This will result in goroutines' leak.
  • jnadro52
    jnadro52 over 8 years
    At least in Go 1.5, there is a client.Go method that is preferable
  • Navid
    Navid about 4 years
    Please 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
    yurenchen about 4 years
    as upstairs @valyala 's comment remind, if server not response, client.call will never return, the goroutine will leak.
  • Shindou-L
    Shindou-L about 2 years
    According my test, rpc.Client.Call method still not exit even I closed the underlying connection