grpc

package
v0.0.0-...-4125756 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2024 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package grpc provides function for managing gRPC system calls (client and server).

Index

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/anthonycorbacho/workspace/api/sample/sampleapp/v1"
	grpckit "github.com/anthonycorbacho/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"

	pb "github.com/anthonycorbacho/workspace/api/sample/sampleapp/v1"
	grpckit "github.com/anthonycorbacho/workspace/kit/grpc"

	grpcretry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
	"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/anthonycorbacho/workspace/api/sample/sampleapp/v1"
	grpckit "github.com/anthonycorbacho/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/anthonycorbacho/workspace/api/sample/sampleapp/v1"
	grpckit "github.com/anthonycorbacho/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.

Jump to

Keyboard shortcuts

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