backoff.go 2.7 KB

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