github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/go-grpc-middleware/retry/examples_test.go (about)

     1  // Copyright 2016 Michal Witkowski. All Rights Reserved.
     2  // See LICENSE for licensing terms.
     3  
     4  package grpc_retry_test
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"time"
    10  
    11  	grpc_retry "github.com/hxx258456/ccgo/go-grpc-middleware/retry"
    12  	pb_testproto "github.com/hxx258456/ccgo/go-grpc-middleware/testing/testproto"
    13  	"github.com/hxx258456/ccgo/grpc"
    14  	"github.com/hxx258456/ccgo/grpc/codes"
    15  	"github.com/hxx258456/ccgo/net/context"
    16  )
    17  
    18  var cc *grpc.ClientConn
    19  
    20  func newCtx(timeout time.Duration) context.Context {
    21  	ctx, _ := context.WithTimeout(context.TODO(), timeout)
    22  	return ctx
    23  }
    24  
    25  // Simple example of using the default interceptor configuration.
    26  func Example_initialization() {
    27  	grpc.Dial("myservice.example.com",
    28  		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor()),
    29  		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor()),
    30  	)
    31  }
    32  
    33  // Complex example with a 100ms linear backoff interval, and retry only on NotFound and Unavailable.
    34  func Example_initializationWithOptions() {
    35  	opts := []grpc_retry.CallOption{
    36  		grpc_retry.WithBackoff(grpc_retry.BackoffLinear(100 * time.Millisecond)),
    37  		grpc_retry.WithCodes(codes.NotFound, codes.Aborted),
    38  	}
    39  	grpc.Dial("myservice.example.com",
    40  		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(opts...)),
    41  		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)),
    42  	)
    43  }
    44  
    45  // Example with an exponential backoff starting with 100ms.
    46  //
    47  // Each next interval is the previous interval multiplied by 2.
    48  func Example_initializationWithExponentialBackoff() {
    49  	opts := []grpc_retry.CallOption{
    50  		grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100 * time.Millisecond)),
    51  	}
    52  	grpc.Dial("myservice.example.com",
    53  		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(opts...)),
    54  		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)),
    55  	)
    56  }
    57  
    58  // Simple example of an idempotent `ServerStream` call, that will be retried automatically 3 times.
    59  func Example_simpleCall() {
    60  	client := pb_testproto.NewTestServiceClient(cc)
    61  	stream, _ := client.PingList(newCtx(1*time.Second), &pb_testproto.PingRequest{}, grpc_retry.WithMax(3))
    62  
    63  	for {
    64  		pong, err := stream.Recv() // retries happen here
    65  		if err == io.EOF {
    66  			break
    67  		} else if err != nil {
    68  			return
    69  		}
    70  		fmt.Printf("got pong: %v", pong)
    71  	}
    72  }
    73  
    74  // This is an example of an `Unary` call that will also retry on deadlines.
    75  //
    76  // Because the passed in context has a `5s` timeout, the whole `Ping` invocation should finish
    77  // within that time. However, by defauly all retried calls will use the parent context for their
    78  // deadlines. This means, that unless you shorten the deadline of each call of the retry, you won't
    79  // be able to retry the first call at all.
    80  //
    81  // `WithPerRetryTimeout` allows you to shorten the deadline of each retry call, allowing you to fit
    82  // multiple retries in the single parent deadline.
    83  func ExampleWithPerRetryTimeout() {
    84  	client := pb_testproto.NewTestServiceClient(cc)
    85  	pong, _ := client.Ping(
    86  		newCtx(5*time.Second),
    87  		&pb_testproto.PingRequest{},
    88  		grpc_retry.WithMax(3),
    89  		grpc_retry.WithPerRetryTimeout(1*time.Second))
    90  
    91  	fmt.Printf("got pong: %v", pong)
    92  }