gitee.com/h79/goutils@v1.22.10/common/scheduler/scheduler.go (about)

     1  package scheduler
     2  
     3  import (
     4  	"gitee.com/h79/goutils/common/algorithm"
     5  	"gitee.com/h79/goutils/common/option"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  type Scheduler struct {
    11  	rm            sync.Mutex
    12  	groups        []*groupScheduled
    13  	groupMod      uint32
    14  	uniqueEnabled bool
    15  	generateFn    GenerateOrInitFunc
    16  }
    17  
    18  var (
    19  	inst *Scheduler
    20  	once sync.Once
    21  )
    22  
    23  func Instance(opts ...option.Option) *Scheduler {
    24  	once.Do(func() {
    25  		inst = newScheduler(20, 2000, opts...)
    26  	})
    27  	return inst
    28  }
    29  
    30  func NewSchedulerCap(groupNum uint32, capacity int, opts ...option.Option) *Scheduler {
    31  	return newScheduler(groupNum, capacity, opts...)
    32  }
    33  
    34  func NewScheduler(groupNum uint32, opts ...option.Option) *Scheduler {
    35  	return newScheduler(groupNum, 5000, opts...)
    36  }
    37  
    38  func newScheduler(groupNum uint32, capacity int, opts ...option.Option) *Scheduler {
    39  	location := option.Select(TimeLocationOpt, time.Local, opts...)
    40  	duration := option.Select(DurationOpt, time.Minute*2, opts...)
    41  	minDuration := option.Select(MinDurationOpt, defTaskDuration, opts...)
    42  	groupNum = option.Select(GroupNumOpt, groupNum, opts...)
    43  	capacity = option.Select(CapacityOpt, capacity, opts...)
    44  	loggerEnabled := option.Select(LoggEnableOpt, false, opts...)
    45  	uniqueEnabled := option.Select(UniqueOpt, false, opts...)
    46  	generateFn := option.Select[GenerateOrInitFunc](GenerateOrInitFnOpt, defaultUpdateFn, opts...)
    47  	if groupNum <= 0 {
    48  		groupNum = 20
    49  	}
    50  	var groups = make([]*groupScheduled, groupNum)
    51  	for i := 0; i < int(groupNum); i++ {
    52  		groups[i] = newGroupScheduled(i, capacity, location, minDuration, duration, loggerEnabled)
    53  	}
    54  	return &Scheduler{
    55  		groupMod:      groupNum,
    56  		groups:        groups,
    57  		uniqueEnabled: uniqueEnabled,
    58  		generateFn:    generateFn,
    59  	}
    60  }
    61  
    62  func (s *Scheduler) groupScheduled(group uint32) *groupScheduled {
    63  	s.rm.Lock()
    64  	defer s.rm.Unlock()
    65  	return s.groups[group]
    66  }
    67  
    68  func (s *Scheduler) GroupIndex(key string) uint32 {
    69  	return algorithm.HashCode(key) % s.groupMod
    70  }
    71  
    72  func (s *Scheduler) Index(id uint32) uint32 {
    73  	return id % s.groupMod
    74  }
    75  
    76  func (s *Scheduler) AddTask(task Task, opts ...option.Option) error {
    77  	return s.AddGTask(s.GroupIndex(task.GetId()), task, opts...)
    78  }
    79  
    80  func (s *Scheduler) AddGTask(group uint32, task Task, opts ...option.Option) error {
    81  	fn := option.Select[GenerateOrInitFunc](GenerateOrInitFnOpt, s.generateFn, opts...)
    82  	uniqueEnabled := option.Select(UniqueOpt, s.uniqueEnabled, opts...)
    83  	groups := s.groupScheduled(group)
    84  	return groups.AddTask(task, uniqueEnabled, fn)
    85  }
    86  
    87  func (s *Scheduler) AddTriggerTask(task Task, trigger Trigger, opts ...option.Option) error {
    88  	return s.AddTriggerGTask(s.GroupIndex(task.GetId()), task, trigger, opts...)
    89  }
    90  
    91  func (s *Scheduler) AddTriggerGTask(group uint32, task Task, trigger Trigger, opts ...option.Option) error {
    92  	fn := option.Select[GenerateOrInitFunc](GenerateOrInitFnOpt, s.generateFn, opts...)
    93  	uniqueEnabled := option.Select(UniqueOpt, s.uniqueEnabled, opts...)
    94  	groups := s.groupScheduled(group)
    95  	return groups.AddTriggerTask(task, trigger, uniqueEnabled, fn)
    96  }
    97  
    98  func (s *Scheduler) UpdateTask(taskId string, opts ...option.Option) bool {
    99  	return s.UpdateGTask(s.GroupIndex(taskId), taskId, opts...)
   100  }
   101  
   102  func (s *Scheduler) UpdateGTask(group uint32, taskId string, opts ...option.Option) bool {
   103  	fn := option.Select[GenerateOrInitFunc](GenerateOrInitFnOpt, s.generateFn, opts...)
   104  	uniqueEnabled := option.Select(UniqueOpt, s.uniqueEnabled, opts...)
   105  	notExistNewFlag := option.Select(NotExistNewOpt, false, opts...)
   106  	groups := s.groupScheduled(group)
   107  	return groups.UpdateTask(taskId, uniqueEnabled, notExistNewFlag, fn)
   108  }
   109  
   110  func (s *Scheduler) ForeachTask(group uint32, update func(group int, task Task, time time.Duration, now, trigger int64) bool) {
   111  	groups := s.groupScheduled(group)
   112  	groups.ForeachTask(update)
   113  }
   114  
   115  func (s *Scheduler) Foreach(update func(group int, task Task, time time.Duration, now, trigger int64) bool) {
   116  	for i := 0; i < len(s.groups); i++ {
   117  		s.groups[i].ForeachTask(update)
   118  	}
   119  }
   120  
   121  func (s *Scheduler) StopTask(taskId string) {
   122  	s.StopGTask(s.GroupIndex(taskId), taskId)
   123  }
   124  
   125  func (s *Scheduler) StopGTask(group uint32, taskId string) {
   126  	groups := s.groupScheduled(group)
   127  	groups.StopTask(taskId)
   128  }
   129  
   130  func (s *Scheduler) RemoveTask(taskId string) {
   131  	s.RemoveGTask(s.GroupIndex(taskId), taskId)
   132  }
   133  
   134  func (s *Scheduler) RemoveGTask(group uint32, taskId string) {
   135  	groups := s.groupScheduled(group)
   136  	groups.RemoveTask(taskId)
   137  }
   138  
   139  func (s *Scheduler) HasTask(taskId string) bool {
   140  	return s.HasGTask(s.GroupIndex(taskId), taskId)
   141  }
   142  
   143  func (s *Scheduler) HasGTask(group uint32, taskId string) bool {
   144  	groups := s.groupScheduled(group)
   145  	return groups.HasTask(taskId)
   146  }
   147  
   148  func (s *Scheduler) Run() {
   149  	s.rm.Lock()
   150  	defer s.rm.Unlock()
   151  	for i := range s.groups {
   152  		s.groups[i].Run()
   153  	}
   154  }