package tasksch import ( "sync" "time" ) const ( TaskStatusBegin = 0 TaskStatusWorking = 0 TaskStatusCanceling = 1 TaskStatusEndBegin = 2 TaskStatusFinished = 2 TaskStatusCanceled = 3 TaskStatusFailed = 4 TaskStatusEnd = 4 ) type ITask interface { Run() *ITask GetResult(duration time.Duration) (retVal []interface{}, err error) Cancel() GetTotalItemCount() int GetFinishedItemCount() int GetTotalJobCount() int GetFinishedJobCount() int GetStatus() int } type BaseTask struct { Name string `json:"name"` ID string `json:"id"` ParallelCount int `json:"parallelCount"` BatchSize int `json:"batchSize"` IsContinueWhenError bool `json:"isContinueWhenError"` CreatedBy string `json:"createdBy"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` TerminatedAt time.Time `json:"terminatedAt"` TotalItemCount int `json:"totalItemCount"` TotalJobCount int `json:"totalJobCount"` FinishedItemCount int `json:"finishedItemCount"` FinishedJobCount int `json:"finishedJobCount"` FailedItemCount int `json:"failedItemCount"` FailedJobCount int `json:"failedJobCount"` Status int `json:"status"` finishChan chan int C <-chan int `json:"-"` params []interface{} quitChan chan int locker sync.RWMutex result interface{} err error } type TaskList []*Task func (s TaskList) Len() int { return len(s) } func (s TaskList) Less(i, j int) bool { return s[i].CreatedAt.Sub(s[j].CreatedAt) < 0 } func (s TaskList) Swap(i, j int) { tmp := s[i] s[i] = s[j] s[j] = tmp } func (t *BaseTask) GetResult(duration time.Duration) (retVal []interface{}, err error) { if t.GetStatus() >= TaskStatusEndBegin { retVal, _ = t.result.([]interface{}) return retVal, t.err } if duration == 0 { duration = time.Hour * 10000 // duration为0表示无限等待 } timer := time.NewTimer(duration) select { case <-t.finishChan: timer.Stop() t.locker.RLock() defer t.locker.RUnlock() retVal, _ = t.result.([]interface{}) return retVal, t.err case <-timer.C: } return nil, ErrTaskNotFinished } func (t *BaseTask) Cancel() { t.locker.Lock() defer t.locker.Unlock() if t.Status < TaskStatusEndBegin && t.Status != TaskStatusCanceling { t.Status = TaskStatusCanceling for i := 0; i < t.ParallelCount; i++ { t.quitChan <- 0 } } } func (t *BaseTask) GetTotalItemCount() int { return t.TotalItemCount } func (t *BaseTask) GetFinishedItemCount() int { t.locker.RLock() defer t.locker.RUnlock() return t.FinishedItemCount } func (t *BaseTask) GetTotalJobCount() int { return t.TotalJobCount } func (t *BaseTask) GetFinishedJobCount() int { t.locker.RLock() defer t.locker.RUnlock() return t.FinishedJobCount } func (t *BaseTask) GetStatus() int { t.locker.RLock() defer t.locker.RUnlock() return t.Status } ///////// func (t *BaseTask) finishedOneJob(itemCount int, err error) { t.locker.Lock() defer t.locker.Unlock() t.UpdatedAt = time.Now() if err == nil { t.FinishedItemCount += itemCount t.FinishedJobCount++ } else { t.FailedItemCount += itemCount t.FailedJobCount++ } } func (t *BaseTask) setStatus(status int) { t.locker.Lock() defer t.locker.Unlock() t.Status = status }