You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

86 lines
1.7 KiB

  1. package retry
  2. import (
  3. "math"
  4. "math/rand"
  5. "time"
  6. )
  7. type Policy interface {
  8. computeWaitTime(failedRetryContext Context) int64
  9. }
  10. func NoWait() Policy {
  11. return &FixedRetryPolicy{
  12. 0,
  13. }
  14. }
  15. func WaitRetryPolicy(sleepTime int64) Policy {
  16. return &FixedRetryPolicy{
  17. sleepTime,
  18. }
  19. }
  20. type FixedRetryPolicy struct {
  21. SleepTime int64
  22. }
  23. func (f *FixedRetryPolicy) computeWaitTime(failedRetryContext Context) int64 {
  24. return f.SleepTime
  25. }
  26. type RandomRetryPolicy struct {
  27. Minimum int64
  28. Maximum int64
  29. }
  30. func (r *RandomRetryPolicy) computeWaitTime(failedRetryContext Context) int64 {
  31. rand := rand.New(rand.NewSource(time.Now().UnixNano()))
  32. t := rand.Int63n(int64(math.Abs(float64(r.Maximum - r.Minimum))))
  33. return t + r.Minimum
  34. }
  35. type IncrementingRetryPolicy struct {
  36. InitWaitTime int64
  37. Increment int64
  38. }
  39. func (i *IncrementingRetryPolicy) computeWaitTime(failedRetryContext Context) int64 {
  40. res := i.InitWaitTime + (i.Increment * int64(failedRetryContext.getRetryTimes()-1))
  41. if res > 0 {
  42. return res
  43. }
  44. return 0
  45. }
  46. type ExponentialRetryPolicy struct {
  47. Multiplier int64
  48. MaximumWait int64
  49. }
  50. func (e *ExponentialRetryPolicy) computeWaitTime(failedRetryContext Context) int64 {
  51. exp := math.Pow(float64(failedRetryContext.getRetryTimes()), 2)
  52. rand := rand.New(rand.NewSource(time.Now().UnixNano()))
  53. t := rand.Int63n(e.Multiplier * int64(exp))
  54. if t > e.MaximumWait {
  55. t = e.MaximumWait
  56. }
  57. if t >= 0 {
  58. return t
  59. }
  60. return 0
  61. }
  62. type CompositeRetryPolicy struct {
  63. WaitPolicies []Policy
  64. }
  65. func (c *CompositeRetryPolicy) computeWaitTime(failedRetryContext Context) int64 {
  66. var waitTime int64 = 0
  67. for _, policy := range c.WaitPolicies {
  68. waitTime += policy.computeWaitTime(failedRetryContext)
  69. }
  70. return waitTime
  71. }