cron_helper.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package cron_helper
  2. import (
  3. "github.com/allanpk716/ChineseSubFinder/internal/logic/downloader_helper"
  4. "github.com/allanpk716/ChineseSubFinder/internal/logic/pre_download_process"
  5. "github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
  6. "github.com/allanpk716/ChineseSubFinder/internal/pkg/settings"
  7. "github.com/robfig/cron/v3"
  8. "sync"
  9. "time"
  10. )
  11. type CronHelper struct {
  12. runImmediately bool
  13. fullSubDownloadProcessing bool
  14. fullSubDownloadProcessingLock sync.Locker
  15. cronHelperRunning bool
  16. c *cron.Cron
  17. dh *downloader_helper.DownloaderHelper
  18. }
  19. func NewCronHelper() (*CronHelper, error) {
  20. ch := CronHelper{}
  21. ch.c = cron.New(cron.WithChain(cron.SkipIfStillRunning(cron.DefaultLogger)))
  22. // 定时器
  23. entryID, err := ch.c.AddFunc("@every "+settings.GetSettings().CommonSettings.ScanInterval, ch.fullSubDownloadProcess)
  24. if err != nil {
  25. log_helper.GetLogger().Errorln("CronHelper Cron entryID:", entryID, "Error:", err)
  26. return nil, err
  27. }
  28. return &ch, nil
  29. }
  30. // Start 开启定时器任务,这个任务是非阻塞的,fullSubDownloadProcess 仅仅可能是这个函数执行耗时而已
  31. // runImmediately == false 那么 ch.c.Start() 是不会阻塞的
  32. func (ch *CronHelper) Start(runImmediately bool) {
  33. ch.runImmediately = runImmediately
  34. // 是否在定时器开启前先执行一次任务
  35. if ch.runImmediately == true {
  36. log_helper.GetLogger().Infoln("First Time fullSubDownloadProcess Start")
  37. ch.fullSubDownloadProcess()
  38. log_helper.GetLogger().Infoln("First Time fullSubDownloadProcess End")
  39. } else {
  40. log_helper.GetLogger().Infoln("RunAtStartup: false, so will not Run At Startup, wait",
  41. settings.GetSettings().CommonSettings.ScanInterval, "to Download")
  42. }
  43. ch.c.Start()
  44. }
  45. // Stop 会阻塞等待任务完成
  46. func (ch *CronHelper) Stop() {
  47. fullSubDownloadProcessing := false
  48. ch.fullSubDownloadProcessingLock.Lock()
  49. fullSubDownloadProcessing = ch.fullSubDownloadProcessing
  50. ch.fullSubDownloadProcessingLock.Unlock()
  51. if fullSubDownloadProcessing == true {
  52. if ch.dh != nil {
  53. ch.dh.Cancel()
  54. }
  55. // Stop stops the cron scheduler if it is running; otherwise it does nothing.
  56. // A context is returned so the caller can wait for running jobs to complete.
  57. nowContext := ch.c.Stop()
  58. select {
  59. case <-time.After(5 * time.Minute):
  60. log_helper.GetLogger().Warningln("Wait over 5 min, CronHelper is timeout")
  61. case <-nowContext.Done():
  62. log_helper.GetLogger().Infoln("CronHelper.Stop() Done.")
  63. }
  64. } else {
  65. // Stop stops the cron scheduler if it is running; otherwise it does nothing.
  66. // A context is returned so the caller can wait for running jobs to complete.
  67. nowContext := ch.c.Stop()
  68. select {
  69. case <-time.After(5 * time.Second):
  70. log_helper.GetLogger().Warningln("Wait over 5 s, CronHelper is timeout")
  71. case <-nowContext.Done():
  72. log_helper.GetLogger().Infoln("CronHelper.Stop() Done.")
  73. }
  74. }
  75. }
  76. func (ch *CronHelper) Running() bool {
  77. defer func() {
  78. ch.fullSubDownloadProcessingLock.Unlock()
  79. }()
  80. ch.fullSubDownloadProcessingLock.Lock()
  81. return ch.fullSubDownloadProcessing
  82. }
  83. // fullSubDownloadProcess 执行一次下载任务的多个步骤
  84. func (ch *CronHelper) fullSubDownloadProcess() {
  85. defer func() {
  86. ch.fullSubDownloadProcessingLock.Lock()
  87. ch.fullSubDownloadProcessing = false
  88. ch.fullSubDownloadProcessingLock.Unlock()
  89. }()
  90. ch.fullSubDownloadProcessingLock.Lock()
  91. ch.fullSubDownloadProcessing = true
  92. ch.fullSubDownloadProcessingLock.Unlock()
  93. // 下载前的初始化
  94. preDownloadProcess := pre_download_process.NewPreDownloadProcess().
  95. Init().
  96. Check().
  97. HotFix().
  98. ChangeSubNameFormat().
  99. ReloadBrowser()
  100. err := preDownloadProcess.Wait()
  101. if err != nil {
  102. log_helper.GetLogger().Errorln("pre_download_process", "Error:", err)
  103. log_helper.GetLogger().Errorln("Skip DownloaderHelper.Start()")
  104. return
  105. }
  106. // 开始下载
  107. ch.dh = downloader_helper.NewDownloaderHelper(*settings.GetSettings(true),
  108. preDownloadProcess.SubSupplierHub)
  109. err = ch.dh.Start()
  110. if err != nil {
  111. log_helper.GetLogger().Errorln("downloader_helper.Start()", "Error:", err)
  112. return
  113. }
  114. }