grpc

package
v0.0.0-...-70e16f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2024 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package gRPC provides an exponential.ErrTransformer that can be used to detect non-retriable errors for gRPC calls. There is no direct support for gRPC streaming in this package.

Example using just defaults:

// This will retry any grpc error codes that are considered retriable.
grpcErrTransform, _ := grpc.New() // Uses defaults

backoff := exponential.WithErrTransformer(grpcErrTransform)

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
req := &pb.HelloRequest{Name: "John"}
var resp *pb.HelloReply{}

err := backoff.Retry(
	ctx,
	func(ctx context.Context, r Record) error {
		var err error
		resp, err = client.SayHello(ctx, req)
		return err
	},
)
cancel()

Example setting an extra code for retries:

// The same as above, except we will retry on codes.DataLoss.
grpcErrTransform, err := grpc.New(WithExtraCodes(codes.DataLoss))
if err != nil {
	// Handle error
}
... // The rest is the same

Example with custom message inspection:

// We are going to provide a function that can inspect a proto.Message when
// the client did not send an error, but there was an error sent back from the server
// in the response.
respHasErr := func (msg proto.Message) error {
	r := msg.(*pb.HelloReply)

	if r.Error != "" {
		if r.PermanentErr {
			// This will stop retries.
			return fmt.Errorf("%s: %w", r.Error, errors.ErrPermanent)
		}
		// We can still retry.
		return fmt.Errorf("%s", r.Error)
	}
	return nil
}
grpcErrTransform, err := grpc.New(WithProtoToErr(respHasErr))
if err != nil {
	// Handle error
}

backoff := exponential.WithErrTransformer(grpcErrTransform)

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
req := &pb.HelloRequest{Name: "John"}
var resp *pb.HelloReply{}

err := backoff.Retry(
	ctx,
	func(ctx context.Context, r Record) error {
		a, err := grpcErrTransform.RespToErr(client.SayHello(ctx, req)) // <- Notice the call wrapper
		if err != nil {
			return err
		}
		resp = a.(*pb.HelloReply)
		return nil
	},
)
cancel()

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option func(t *Transformer) error

Option is an option for the New() constructor.

func WithExtraCodes

func WithExtraCodes(extras ...codes.Code) Option

WithExtraCodes defines extra grpc status codes that are considered retriable.

func WithProtoToErrs

func WithProtoToErrs(protosToErrs ...ProtoToErr) Option

WithProtoToErrs pass functions that look at protocol buffer message responses to determine if the message actually indicates an error.

type ProtoToErr

type ProtoToErr func(msg proto.Message) error

ProtoToErr inspects a protocol buffer message and determines if the call was really an error. If it was not, this returns nil.

type Transformer

type Transformer struct {
	// contains filtered or unexported fields
}

Transformer provides an ErrTransformer method that can be used to detect non-retriable errors. The following codes are retriable: Canceled, DeadlineExceeded, Unknown, Internal, Unavailable, ResourceExhausted. Any other code is not.

func New

func New(options ...Option) (*Transformer, error)

New returns a new Transformer. This implements exponential.ErrTransformer with the method ErrTransformer. You can add other codes that are retriable by passing them as arguments. This list of retriable codes are listed on Transformer.

func (*Transformer) ErrTransformer

func (t *Transformer) ErrTransformer(err error) error

ErrTransformer returns a transformer that can be used to detect non-retriable errors. If it is non-retriable it will wrap the error with errors.ErrPermanent.

func (*Transformer) RespToErr

func (t *Transformer) RespToErr(r proto.Message, err error) (proto.Message, error)

RespToErr takes a proto.Message and an error from a call from a protocol buffer client call method and returns the Response and an error. If error != nil , this simply return the values passed. Otherwise it will inspect the Response accord to rules passed to New() to determine if we have an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL