backoff.go (2377B)
1 /* 2 * 3 * Copyright 2017 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package backoff implement the backoff strategy for gRPC. 20 // 21 // This is kept in internal until the gRPC project decides whether or not to 22 // allow alternative backoff strategies. 23 package backoff 24 25 import ( 26 "time" 27 28 grpcbackoff "google.golang.org/grpc/backoff" 29 "google.golang.org/grpc/internal/grpcrand" 30 ) 31 32 // Strategy defines the methodology for backing off after a grpc connection 33 // failure. 34 type Strategy interface { 35 // Backoff returns the amount of time to wait before the next retry given 36 // the number of consecutive failures. 37 Backoff(retries int) time.Duration 38 } 39 40 // DefaultExponential is an exponential backoff implementation using the 41 // default values for all the configurable knobs defined in 42 // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. 43 var DefaultExponential = Exponential{Config: grpcbackoff.DefaultConfig} 44 45 // Exponential implements exponential backoff algorithm as defined in 46 // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. 47 type Exponential struct { 48 // Config contains all options to configure the backoff algorithm. 49 Config grpcbackoff.Config 50 } 51 52 // Backoff returns the amount of time to wait before the next retry given the 53 // number of retries. 54 func (bc Exponential) Backoff(retries int) time.Duration { 55 if retries == 0 { 56 return bc.Config.BaseDelay 57 } 58 backoff, max := float64(bc.Config.BaseDelay), float64(bc.Config.MaxDelay) 59 for backoff < max && retries > 0 { 60 backoff *= bc.Config.Multiplier 61 retries-- 62 } 63 if backoff > max { 64 backoff = max 65 } 66 // Randomize backoff delays so that if a cluster of requests start at 67 // the same time, they won't operate in lockstep. 68 backoff *= 1 + bc.Config.Jitter*(grpcrand.Float64()*2-1) 69 if backoff < 0 { 70 return 0 71 } 72 return time.Duration(backoff) 73 }