retry.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package rag
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. )
  7. // RetryConfig 重试配置
  8. type RetryConfig struct {
  9. MaxAttempts int
  10. InitialDelay time.Duration
  11. MaxDelay time.Duration
  12. BackoffFactor float64
  13. }
  14. // DefaultRetryConfig 默认重试配置
  15. func DefaultRetryConfig() RetryConfig {
  16. return RetryConfig{
  17. MaxAttempts: 3,
  18. InitialDelay: 100 * time.Millisecond,
  19. MaxDelay: 5 * time.Second,
  20. BackoffFactor: 2.0,
  21. }
  22. }
  23. // Retry 重试执行函数
  24. func Retry(ctx context.Context, config RetryConfig, fn func() error) error {
  25. var lastErr error
  26. delay := config.InitialDelay
  27. for attempt := 0; attempt < config.MaxAttempts; attempt++ {
  28. // 检查上下文是否已取消
  29. select {
  30. case <-ctx.Done():
  31. return ctx.Err()
  32. default:
  33. }
  34. // 执行函数
  35. err := fn()
  36. if err == nil {
  37. return nil
  38. }
  39. lastErr = err
  40. // 如果不是最后一次尝试,等待后重试
  41. if attempt < config.MaxAttempts-1 {
  42. select {
  43. case <-ctx.Done():
  44. return ctx.Err()
  45. case <-time.After(delay):
  46. // 指数退避
  47. delay = time.Duration(float64(delay) * config.BackoffFactor)
  48. if delay > config.MaxDelay {
  49. delay = config.MaxDelay
  50. }
  51. }
  52. }
  53. }
  54. return fmt.Errorf("重试 %d 次后仍然失败: %w", config.MaxAttempts, lastErr)
  55. }