Documentation ¶
Overview ¶
Package grpc provides function for managing gRPC system calls (client and server).
Index ¶
- func NewClient(addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
- func NewServer(opts ...grpc.ServerOption) *grpc.Server
- func WithCodes(retryCodes ...codes.Code) grpcretry.CallOption
- func WithMaxRetries(maxRetries uint) grpcretry.CallOption
- func WithPerRetryTimeout(timeout time.Duration) grpcretry.CallOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewClient ¶
func NewClient(addr string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
NewClient create a new gRPC client setup for observability and retry.
By default, the reties *are disabled*, preventing accidental use of retries. You can easily override the number of retries (setting them to more than 0) with a `grpc.ClientOption`, e.g.:
myclient.Ping(ctx, goodPing, grpckit.WithMaxRetries(5))
Other default options are: retry on `ResourceExhausted` and `Unavailable` gRPC codes, use a 50ms linear backoff with 10% jitter.
See: https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-middleware/retry
Example ¶
Sample client using the default configuration.
package main import ( "context" "fmt" pb "github.com/mukhtarkv/workspace/api/sample/sampleapp/v1" grpckit "github.com/mukhtarkv/workspace/kit/grpc" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) func main() { cc, err := grpckit.NewClient( "service.namespace.svc.cluster.local:8081", // address of the grpc service grpc.WithTransportCredentials(insecure.NewCredentials()), // required transport cred, set to insecure ) if err != nil { // handle error } // Pass the grpc client connection to the grpc client API client := pb.NewSampleAppClient(cc) // perform a client request resp, err := client.Fetch( context.Background(), &pb.FetchRequest{Id: "43"}, ) if err != nil { // handle client call error from the grpc server } // handle the client response fmt.Println(resp) }
Output:
Example (WithCustomRetry) ¶
Client with custom retry that apply retry to all endpoints
package main import ( "context" "fmt" "time" grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry" pb "github.com/mukhtarkv/workspace/api/sample/sampleapp/v1" grpckit "github.com/mukhtarkv/workspace/kit/grpc" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" ) func main() { cc, err := grpckit.NewClient( "service.namespace.svc.cluster.local:8081", // address of the grpc service grpc.WithTransportCredentials(insecure.NewCredentials()), // required transport cred, set to insecure grpc.WithChainUnaryInterceptor( // define a custom retry interceptor grpcretry.UnaryClientInterceptor( // define a new retry of backoff; Exponential backoff with jitter grpcretry.WithBackoff(grpcretry.BackoffExponentialWithJitter(50*time.Millisecond, 0.1)), grpckit.WithMaxRetries(5), // retry policy for all endpoints grpckit.WithCodes(codes.Aborted), // retry policy code for all endpoints ), ), ) if err != nil { // handle error } // Pass the grpc client connection to the grpc client API client := pb.NewSampleAppClient(cc) // perform a client request // if the request fail with status `ResourceExhausted` or `Unavailable` or `Aborted`, // it will retry 5 times exponentially. resp, err := client.Fetch( context.Background(), &pb.FetchRequest{Id: "43"}, ) if err != nil { // handle client call error from the grpc server } // handle the client response fmt.Println(resp) }
Output:
Example (WithRetry) ¶
Sample client using the default configuration. and pass retry upon failure. By default, retry on `ResourceExhausted` and `Unavailable` gRPC codes, use a 50ms linear backoff with 10% jitter.
package main import ( "context" "fmt" pb "github.com/mukhtarkv/workspace/api/sample/sampleapp/v1" grpckit "github.com/mukhtarkv/workspace/kit/grpc" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) func main() { cc, err := grpckit.NewClient( "service.namespace.svc.cluster.local:8081", // address of the grpc service grpc.WithTransportCredentials(insecure.NewCredentials()), // required transport cred, set to insecure ) if err != nil { // handle error } // Pass the grpc client connection to the grpc client API client := pb.NewSampleAppClient(cc) // perform a client request resp, err := client.Fetch( context.Background(), &pb.FetchRequest{Id: "43"}, grpckit.WithMaxRetries(5), // retry 5 times ) if err != nil { // handle client call error from the grpc server } // handle the client response fmt.Println(resp) }
Output:
Example (WithRetryAndCodes) ¶
Sample client using the default configuration. and pass retry upon failure. Retry on `ResourceExhausted` and `Unavailable` and `Aborted` gRPC codes, use a 50ms linear backoff with 10% jitter.
package main import ( "context" "fmt" pb "github.com/mukhtarkv/workspace/api/sample/sampleapp/v1" grpckit "github.com/mukhtarkv/workspace/kit/grpc" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" ) func main() { cc, err := grpckit.NewClient( "service.namespace.svc.cluster.local:8081", // address of the grpc service grpc.WithTransportCredentials(insecure.NewCredentials()), // required transport cred, set to insecure ) if err != nil { // handle error } // Pass the grpc client connection to the grpc client API client := pb.NewSampleAppClient(cc) // perform a client request resp, err := client.Fetch( context.Background(), &pb.FetchRequest{Id: "43"}, grpckit.WithMaxRetries(5), // retry 5 times grpckit.WithCodes(codes.Aborted), // add a new code to the list of retry ) if err != nil { // handle client call error from the grpc server } // handle the client response fmt.Println(resp) }
Output:
func NewServer ¶
func NewServer(opts ...grpc.ServerOption) *grpc.Server
NewServer creates a gRPC server that will be by default recover from panic and setup for observability.
func WithCodes ¶
func WithCodes(retryCodes ...codes.Code) grpcretry.CallOption
WithCodes sets which codes should be retried.
Please *use with care*, as you may be retrying non-idempotent calls.
You cannot automatically retry on Cancelled and Deadline, please use `WithPerRetryTimeout` for these.
func WithMaxRetries ¶
func WithMaxRetries(maxRetries uint) grpcretry.CallOption
WithMaxRetries sets the maximum number of retries on this call, or this interceptor.
func WithPerRetryTimeout ¶
func WithPerRetryTimeout(timeout time.Duration) grpcretry.CallOption
WithPerRetryTimeout sets the RPC timeout per call (including initial call) on this call, or this interceptor.
The context.Deadline of the call takes precedence and sets the maximum time the whole invocation will take, but WithPerRetryTimeout can be used to limit the RPC time per each call.
For example, with context.Deadline = now + 10s, and WithPerRetryTimeout(3 * time.Seconds), each of the retry calls (including the initial one) will have a deadline of now + 3s.
A value of 0 disables the timeout overrides completely and returns to each retry call using the parent `context.Deadline`.
Note that when this is enabled, any DeadlineExceeded errors that are propagated up will be retried.
Types ¶
This section is empty.