OSDN Git Service

new repo
[bytom/vapor.git] / vendor / google.golang.org / grpc / backoff.go
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 grpc
20
21 import (
22         "math/rand"
23         "time"
24 )
25
26 // DefaultBackoffConfig uses values specified for backoff in
27 // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md.
28 var DefaultBackoffConfig = BackoffConfig{
29         MaxDelay:  120 * time.Second,
30         baseDelay: 1.0 * time.Second,
31         factor:    1.6,
32         jitter:    0.2,
33 }
34
35 // backoffStrategy defines the methodology for backing off after a grpc
36 // connection failure.
37 //
38 // This is unexported until the gRPC project decides whether or not to allow
39 // alternative backoff strategies. Once a decision is made, this type and its
40 // method may be exported.
41 type backoffStrategy interface {
42         // backoff returns the amount of time to wait before the next retry given
43         // the number of consecutive failures.
44         backoff(retries int) time.Duration
45 }
46
47 // BackoffConfig defines the parameters for the default gRPC backoff strategy.
48 type BackoffConfig struct {
49         // MaxDelay is the upper bound of backoff delay.
50         MaxDelay time.Duration
51
52         // TODO(stevvooe): The following fields are not exported, as allowing
53         // changes would violate the current gRPC specification for backoff. If
54         // gRPC decides to allow more interesting backoff strategies, these fields
55         // may be opened up in the future.
56
57         // baseDelay is the amount of time to wait before retrying after the first
58         // failure.
59         baseDelay time.Duration
60
61         // factor is applied to the backoff after each retry.
62         factor float64
63
64         // jitter provides a range to randomize backoff delays.
65         jitter float64
66 }
67
68 func setDefaults(bc *BackoffConfig) {
69         md := bc.MaxDelay
70         *bc = DefaultBackoffConfig
71
72         if md > 0 {
73                 bc.MaxDelay = md
74         }
75 }
76
77 func (bc BackoffConfig) backoff(retries int) time.Duration {
78         if retries == 0 {
79                 return bc.baseDelay
80         }
81         backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay)
82         for backoff < max && retries > 0 {
83                 backoff *= bc.factor
84                 retries--
85         }
86         if backoff > max {
87                 backoff = max
88         }
89         // Randomize backoff delays so that if a cluster of requests start at
90         // the same time, they won't operate in lockstep.
91         backoff *= 1 + bc.jitter*(rand.Float64()*2-1)
92         if backoff < 0 {
93                 return 0
94         }
95         return time.Duration(backoff)
96 }