Documentation ¶
Overview ¶
Package rpc provides goma specific rpc features on gRPC.
Load balancing RPC client ¶
gRPC doesn't provide good loadbalancing client (for kubernetes, yet). Typical gRPC client could be created as follows:
conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn)
This package provides load balancing client if address has multiple IP addresses:
type GreeterClient struct { c *rpc.Client } func NewGreeterClient(address string, opts ...grpc.DialOption) GreeterClient { return GreeterClient{ c: rpc.NewClient(address, func(cc *grpc.ClientConn) interface{} { return pb.NewGreeterClient(cc) }, opts...), } } func (c GreeterClient) SayHello(ctx context.Context, in *pb.Req, opts...grpc.CallOption) (*pb.Resp, error) { var resp *pb.Resp var err error err = c.Call(ctx, c.client.Pick, "", func(client interface{}) error { resp, err = client.(GreeterClient).SayHello(ctx, in, opts...) return err }, ) return resp, err } c := NewGreeterClient(address, grpc.WithInsecure())
rpc call would return codes.Unavailable if no backends available for address.
TODO: use grpc's Balancer? TODO: use statefulset for sharding?
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Render ¶
func Render(w http.ResponseWriter, req *http.Request)
Render renders backend information. It is handled on /debug/backends on default http mux.
func RequestID ¶
func RequestID(r *gomapb.RequesterInfo) string
RequestID returns string identifier of this request.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents load-balancing client.
func NewClient ¶
func NewClient(ctx context.Context, target string, newc func(cc *grpc.ClientConn) interface{}, opts ...Option) *Client
NewClient creates new load-balancing client. newc should return grpc client interface for given *grpc.ClientConn. target is <hostname>:<port>. TODO: support grpc new naming?
func (*Client) Call ¶
func (c *Client) Call(ctx context.Context, picker func(context.Context, interface{}) (*backend, error), key interface{}, f func(interface{}) error) error
Call calls new rpc call. picker and key will be used to pick backend. picker will be Client's Pick, or Shard. Pick will use key for backend addr, or empty for least loaded. Shard will use key for sharding. Rand will use key for *RandomState. f is called with grpc client inferface for selected backend.
type Option ¶
type Option func(*Client)
Option configures Client.
func DialOption ¶
func DialOption(opt grpc.DialOption) Option
DialOption returns an Option to configure dial option.
func DialOptions ¶
func DialOptions(opts ...grpc.DialOption) []Option
DialOptions converts grpc.DialOptions to Options.
type RetriableError ¶
RetriableError represents retriable error in Retry.Do.
func (RetriableError) Error ¶
func (e RetriableError) Error() string
type Retry ¶
type Retry struct { // MaxRetry represents how many times to retry. // If it is not positive, it retries while error is // codes.Unavailable or codes.ResourceExhausted. MaxRetry int BaseDelay time.Duration MaxDelay time.Duration // backoff factor. default is 1.6 Factor float64 }
Retry handles rpc retry.
func (Retry) Do ¶
Do calls f with retry, while f returns RetriableError, codes.Unavailable or codes.ResourceExhausted. It returns codes.DeadlineExceeded if ctx is cancelled. It returns last error if f returns error other than codes.Unavailable or codes.ResourceExhausted, or it reaches too many retries. It respects RetriableError.Delay or errdetail RetryInfo if it is specified as error details.