gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/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 "gitee.com/ks-custle/core-gm/go-grpc-middleware/retry" 12 pb_testproto "gitee.com/ks-custle/core-gm/go-grpc-middleware/testing/testproto" 13 "gitee.com/ks-custle/core-gm/grpc" 14 "gitee.com/ks-custle/core-gm/grpc/codes" 15 "gitee.com/ks-custle/core-gm/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 }