Does the RPC have a timeout mechanism?

If RPC does not have a timeout mechanism, how can I “kill” an RPC call if it tries to call the closed server RPC method?

+5
source share
4 answers

You can use channels to implement the 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
}

selectwill be blocked until client.Callit returns or expires timeoutNanoseconds.

+8
source

- ( ), rpc.Dial net.DialTimeout( , : rpc vs net). , ( ); "".

  conn, err := net.DialTimeout("tcp", "localhost:8080", time.Minute)
  if err != nil {
    log.Fatal("dialing:", err)
  }

  client := rpc.NewClient(conn)
+3

, net/rpc - , . " ".

- https://github.com/valyala/gorpc, RPC .

0

, , - . . (context.DeadlineExceeded)

import (
    "context"
    "log"
    "net/rpc"
)

type Client struct {
    *rpc.Client
}

// CallEx is a context aware wrapper around rpc Client.Call()
func (c *client) CallEx(ctx context.Context, serviceMethod string, args interface{}, reply interface{}) error {
    ec := make(chan error, 1)
    go func() {
        ec <- c.Call(serviceMethod, args, reply)
    }()
    select {
    case err := <-ec:
        return err
    case <-ctx.Done():
        return ctx.Err()
    }
}

Deadline:

type Args struct {
   A, B int
}

func main(){
    rpc, err := rpc.DialHTTP("tcp", "host")
    if err != nil {
        t.Fatal(err)
    }
    c := client{rpc}

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    var i int
    if err := c.CallEx(ctx, "Calc.Multiply", Args{2, 2}, &i); err != nil {
        log.Fatal(err)
    }
}
0

Source: https://habr.com/ru/post/1538326/


All Articles