retry.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package util
  2. import (
  3. "strings"
  4. "time"
  5. "github.com/seaweedfs/seaweedfs/weed/glog"
  6. )
  7. var RetryWaitTime = 6 * time.Second
  8. func Retry(name string, job func() error) (err error) {
  9. waitTime := time.Second
  10. hasErr := false
  11. for waitTime < RetryWaitTime {
  12. err = job()
  13. if err == nil {
  14. if hasErr {
  15. glog.V(0).Infof("retry %s successfully", name)
  16. }
  17. waitTime = time.Second
  18. break
  19. }
  20. if strings.Contains(err.Error(), "transport") {
  21. hasErr = true
  22. glog.V(0).Infof("retry %s: err: %v", name, err)
  23. } else {
  24. break
  25. }
  26. time.Sleep(waitTime)
  27. waitTime += waitTime / 2
  28. }
  29. return err
  30. }
  31. func MultiRetry(name string, errList []string, job func() error) (err error) {
  32. waitTime := time.Second
  33. hasErr := false
  34. for waitTime < RetryWaitTime {
  35. err = job()
  36. if err == nil {
  37. if hasErr {
  38. glog.V(0).Infof("retry %s successfully", name)
  39. }
  40. waitTime = time.Second
  41. break
  42. }
  43. if containErr(err.Error(), errList) {
  44. hasErr = true
  45. glog.V(0).Infof("retry %s: err: %v", name, err)
  46. } else {
  47. break
  48. }
  49. time.Sleep(waitTime)
  50. waitTime += waitTime / 2
  51. }
  52. return err
  53. }
  54. // RetryUntil retries until the job returns no error or onErrFn returns false
  55. func RetryUntil(name string, job func() error, onErrFn func(err error) (shouldContinue bool)) {
  56. waitTime := time.Second
  57. for {
  58. err := job()
  59. if err == nil {
  60. waitTime = time.Second
  61. break
  62. }
  63. if onErrFn(err) {
  64. if strings.Contains(err.Error(), "transport") {
  65. glog.V(0).Infof("retry %s: err: %v", name, err)
  66. }
  67. time.Sleep(waitTime)
  68. if waitTime < RetryWaitTime {
  69. waitTime += waitTime / 2
  70. }
  71. continue
  72. } else {
  73. break
  74. }
  75. }
  76. }
  77. // Nvl return the first non-empty string
  78. func Nvl(values ...string) string {
  79. for _, s := range values {
  80. if s != "" {
  81. return s
  82. }
  83. }
  84. return ""
  85. }
  86. func containErr(err string, errList []string) bool {
  87. for _, e := range errList {
  88. if strings.Contains(err, e) {
  89. return true
  90. }
  91. }
  92. return false
  93. }