timing_wheel_service.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package service
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. "github.com/Wei-Shaw/sub2api/internal/pkg/logger"
  7. "github.com/zeromicro/go-zero/core/collection"
  8. )
  9. var newTimingWheel = collection.NewTimingWheel
  10. // TimingWheelService wraps go-zero's TimingWheel for task scheduling
  11. type TimingWheelService struct {
  12. tw *collection.TimingWheel
  13. stopOnce sync.Once
  14. }
  15. // NewTimingWheelService creates a new TimingWheelService instance
  16. func NewTimingWheelService() (*TimingWheelService, error) {
  17. // 1 second tick, 3600 slots = supports up to 1 hour delay
  18. // execute function: runs func() type tasks
  19. tw, err := newTimingWheel(1*time.Second, 3600, func(key, value any) {
  20. if fn, ok := value.(func()); ok {
  21. fn()
  22. }
  23. })
  24. if err != nil {
  25. return nil, fmt.Errorf("创建 timing wheel 失败: %w", err)
  26. }
  27. return &TimingWheelService{tw: tw}, nil
  28. }
  29. // Start starts the timing wheel
  30. func (s *TimingWheelService) Start() {
  31. logger.LegacyPrintf("service.timing_wheel", "%s", "[TimingWheel] Started (auto-start by go-zero)")
  32. }
  33. // Stop stops the timing wheel
  34. func (s *TimingWheelService) Stop() {
  35. s.stopOnce.Do(func() {
  36. s.tw.Stop()
  37. logger.LegacyPrintf("service.timing_wheel", "%s", "[TimingWheel] Stopped")
  38. })
  39. }
  40. // Schedule schedules a one-time task
  41. func (s *TimingWheelService) Schedule(name string, delay time.Duration, fn func()) {
  42. if err := s.tw.SetTimer(name, fn, delay); err != nil {
  43. logger.LegacyPrintf("service.timing_wheel", "[TimingWheel] SetTimer failed for %q: %v", name, err)
  44. }
  45. }
  46. // ScheduleRecurring schedules a recurring task
  47. func (s *TimingWheelService) ScheduleRecurring(name string, interval time.Duration, fn func()) {
  48. var schedule func()
  49. schedule = func() {
  50. fn()
  51. if err := s.tw.SetTimer(name, schedule, interval); err != nil {
  52. logger.LegacyPrintf("service.timing_wheel", "[TimingWheel] recurring SetTimer failed for %q: %v", name, err)
  53. }
  54. }
  55. if err := s.tw.SetTimer(name, schedule, interval); err != nil {
  56. logger.LegacyPrintf("service.timing_wheel", "[TimingWheel] initial SetTimer failed for %q: %v", name, err)
  57. }
  58. }
  59. // Cancel cancels a scheduled task
  60. func (s *TimingWheelService) Cancel(name string) {
  61. _ = s.tw.RemoveTimer(name)
  62. }