crontab.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package crontab
  2. import (
  3. "errors"
  4. "github.com/robfig/cron/v3"
  5. "sync"
  6. )
  7. var (
  8. ErrParam = errors.New("没有传递必要的参数")
  9. )
  10. // cronManageInstance
  11. // 全局唯一实例
  12. var cronManageInstance *CronManage
  13. // CronManage
  14. // 定时任务管理器类型 单例
  15. type CronManage struct {
  16. crons map[string]*CronJobs
  17. mutex *sync.Mutex
  18. }
  19. // NewCronManage
  20. // 创建管理器
  21. func NewCronManage() *CronManage {
  22. if cronManageInstance != nil {
  23. return cronManageInstance
  24. }
  25. cronManageInstance = &CronManage{
  26. crons: make(map[string]*CronJobs),
  27. mutex: &sync.Mutex{},
  28. }
  29. return cronManageInstance
  30. }
  31. // GetCron
  32. // 创建定时管理器
  33. func GetCron(cronName string) *CronJobs {
  34. if cj, ok := cronManageInstance.getCronJobs(cronName); ok {
  35. return cj
  36. }
  37. cj := newCronJobs(cronName)
  38. cronManageInstance.setCronJobs(cronName, cj)
  39. return cj
  40. }
  41. func GetCrons() map[string]*CronJobs {
  42. return cronManageInstance.crons
  43. }
  44. func (cm *CronManage) getCronJobs(cronName string) (*CronJobs, bool) {
  45. cm.mutex.Lock()
  46. defer cm.mutex.Unlock()
  47. cj, ok := cm.crons[cronName]
  48. return cj, ok
  49. }
  50. func (cm *CronManage) setCronJobs(cronName string, cj *CronJobs) {
  51. cm.mutex.Lock()
  52. defer cm.mutex.Unlock()
  53. cm.crons[cronName] = cj
  54. }
  55. // DestroyCronManage 销毁实例
  56. func DestroyCronManage() {
  57. for _, cronJobs := range cronManageInstance.crons {
  58. cronJobs.Destroy()
  59. }
  60. cronManageInstance.crons = make(map[string]*CronJobs)
  61. }
  62. type CronJobs struct {
  63. // 定时器名称
  64. name string
  65. // 定时器句柄
  66. cronHandle *cron.Cron
  67. // 此定时器中启动的工作任务
  68. jobs map[string]int
  69. // map锁
  70. mutex *sync.Mutex
  71. }
  72. type JobInfo struct {
  73. JobName string `json:"jobName"`
  74. JobId string `json:"jobId"`
  75. NextTime string `json:"nextTime"`
  76. Valid bool `json:"valid"`
  77. }
  78. func newCronJobs(name string) *CronJobs {
  79. cronHandle := cron.New(cron.WithSeconds())
  80. cronHandle.Start()
  81. return &CronJobs{
  82. name: name,
  83. cronHandle: cronHandle,
  84. jobs: make(map[string]int),
  85. mutex: &sync.Mutex{},
  86. }
  87. }
  88. func (cj *CronJobs) getCronHandle() *cron.Cron {
  89. return cj.cronHandle
  90. }
  91. func (cj *CronJobs) getJobID(jobName string) (int, bool) {
  92. cj.mutex.Lock()
  93. defer cj.mutex.Unlock()
  94. jobID, ok := cj.jobs[jobName]
  95. return jobID, ok
  96. }
  97. func (cj *CronJobs) setJobID(jobName string, jobID int) {
  98. cj.mutex.Lock()
  99. defer cj.mutex.Unlock()
  100. cj.jobs[jobName] = jobID
  101. }
  102. func (cj *CronJobs) deleteJobID(jobName string) {
  103. cj.mutex.Lock()
  104. defer cj.mutex.Unlock()
  105. delete(cj.jobs, jobName)
  106. }
  107. // AddJobWithNoParams
  108. // 新增任务,任务处理函数无需参数
  109. func (cj *CronJobs) AddJobWithNoParams(jobName string, spec string, jobFunc func()) error {
  110. if jobName == "" || spec == "" || jobFunc == nil {
  111. return ErrParam
  112. }
  113. if _, ok := cj.getJobID(jobName); ok {
  114. return nil
  115. }
  116. entryID, err := cj.cronHandle.AddFunc(spec, jobFunc)
  117. if err != nil {
  118. return err
  119. }
  120. cj.setJobID(jobName, int(entryID))
  121. return nil
  122. }
  123. // AddJobWithParams
  124. // 新增任务,任务处理函数需要参数
  125. func (cj *CronJobs) AddJobWithParams(jobName string, spec string, jobInterface cron.Job) error {
  126. if jobName == "" || spec == "" || jobInterface == nil {
  127. return ErrParam
  128. }
  129. if _, ok := cj.getJobID(jobName); ok {
  130. return nil
  131. }
  132. entryId, err := cj.cronHandle.AddJob(spec, jobInterface)
  133. if err != nil {
  134. return err
  135. }
  136. cj.setJobID(jobName, int(entryId))
  137. return nil
  138. }
  139. // GetJobs
  140. // 获取当前定时器中的任务
  141. func (cj *CronJobs) GetJobs() []*JobInfo {
  142. jobInfos := make([]*JobInfo, 0)
  143. for jobName, entryId := range cj.jobs {
  144. entry := cj.cronHandle.Entry(cron.EntryID(entryId))
  145. jobInfo := &JobInfo{
  146. JobName: jobName,
  147. JobId: string(rune(entry.ID)),
  148. NextTime: entry.Next.UTC().String(),
  149. Valid: entry.Valid(),
  150. }
  151. jobInfos = append(jobInfos, jobInfo)
  152. }
  153. return jobInfos
  154. }
  155. // StopCron
  156. // 停止定时器
  157. func (cj *CronJobs) StopCron() {
  158. cj.cronHandle.Stop()
  159. }
  160. // RemoveJob
  161. // 删除任务
  162. func (cj *CronJobs) RemoveJob(jobName string) error {
  163. jobId, ok := cj.getJobID(jobName)
  164. if !ok {
  165. return nil
  166. }
  167. cj.cronHandle.Remove(cron.EntryID(jobId))
  168. cj.deleteJobID(jobName)
  169. return nil
  170. }
  171. func (cj *CronJobs) Destroy() {
  172. //删除所有任务
  173. for jobName, _ := range cj.jobs {
  174. _ = cj.RemoveJob(jobName)
  175. }
  176. //停止定时器
  177. cj.StopCron()
  178. }