backoff.go 2.7 KB

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