utils.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package utils
  2. import (
  3. "log/slog"
  4. "runtime"
  5. "time"
  6. )
  7. // RetryStrategy specifies a strategy to retry an operation after waiting a while,
  8. // with hooks for successful and unsuccessful (>=max) tries.
  9. type RetryStrategy struct {
  10. Wait func(time.Duration)
  11. WaitTime time.Duration
  12. WaitTimeIncrease time.Duration
  13. MaxTries int
  14. Try func() error
  15. OnMaxTries func()
  16. OnSuccess func()
  17. }
  18. // DoStrategy does the retry strategy specified in the struct, waiting before retrying an operator,
  19. // up to a max number of tries, and if executes a success "finalizer" operation if a retry is successful
  20. func (rs RetryStrategy) DoStrategy() {
  21. err := rs.Try()
  22. if err == nil {
  23. rs.OnSuccess()
  24. return
  25. }
  26. tries := 1
  27. for {
  28. if tries >= rs.MaxTries {
  29. rs.OnMaxTries()
  30. return
  31. }
  32. rs.Wait(rs.WaitTime)
  33. if err := rs.Try(); err != nil {
  34. tries++ // we tried, increase count
  35. rs.WaitTime += rs.WaitTimeIncrease // for the next time, sleep more
  36. continue // retry
  37. }
  38. rs.OnSuccess()
  39. return
  40. }
  41. }
  42. func TraceCaller() {
  43. // Skip 1 frame to get the caller of this function
  44. pc, file, line, ok := runtime.Caller(2)
  45. if !ok {
  46. slog.Debug("Unable to get caller information")
  47. return
  48. }
  49. // Get function name from the program counter (pc)
  50. funcName := runtime.FuncForPC(pc).Name()
  51. // Print trace details
  52. slog.Debug("Called from function: %s\n", "func-name", funcName)
  53. slog.Debug("File: %s, Line: %d\n", "file", file, "line-no", line)
  54. }