Files
jiacrontab/pkg/crontab/crontab.go
jiazhizhong 1279635d7f fix
2022-03-10 17:09:03 +08:00

89 lines
1.4 KiB
Go

package crontab
import (
"container/heap"
"errors"
"jiacrontab/pkg/pqueue"
"sync"
"time"
)
// Task 任务
type Task = pqueue.Item
type Crontab struct {
pq pqueue.PriorityQueue
mux sync.RWMutex
ready chan *Task
}
func New() *Crontab {
return &Crontab{
pq: pqueue.New(10000),
ready: make(chan *Task, 10000),
}
}
// AddJob 添加未经处理的job
func (c *Crontab) AddJob(j *Job) error {
nt, err := j.NextExecutionTime(time.Now())
if err != nil {
return errors.New("Invalid execution time")
}
c.mux.Lock()
heap.Push(&c.pq, &Task{
Priority: nt.UnixNano(),
Value: j,
})
c.mux.Unlock()
return nil
}
// AddJob 添加延时任务
func (c *Crontab) AddTask(t *Task) {
c.mux.Lock()
heap.Push(&c.pq, t)
c.mux.Unlock()
}
func (c *Crontab) Len() int {
c.mux.RLock()
len := len(c.pq)
c.mux.RUnlock()
return len
}
func (c *Crontab) GetAllTask() []*Task {
c.mux.Lock()
list := c.pq
c.mux.Unlock()
return list
}
func (c *Crontab) Ready() <-chan *Task {
return c.ready
}
func (c *Crontab) QueueScanWorker() {
refreshTicker := time.NewTicker(20 * time.Millisecond)
for {
select {
case <-refreshTicker.C:
if len(c.pq) == 0 {
continue
}
start:
c.mux.Lock()
now := time.Now().UnixNano()
job, _ := c.pq.PeekAndShift(now)
c.mux.Unlock()
if job == nil {
continue
}
c.ready <- job
goto start
}
}
}