Beego/adapter/toolbox/task.go

292 lines
7.1 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package toolbox
import (
"context"
"sort"
"time"
"github.com/astaxie/beego/task"
)
// The bounds for each field.
var (
AdminTaskList map[string]Tasker
)
const (
// Set the top bit if a star was included in the expression.
starBit = 1 << 63
)
// Schedule time taks schedule
type Schedule task.Schedule
// TaskFunc task func type
type TaskFunc func() error
// Tasker task interface
type Tasker interface {
GetSpec() string
GetStatus() string
Run() error
SetNext(time.Time)
GetNext() time.Time
SetPrev(time.Time)
GetPrev() time.Time
}
// task error
type taskerr struct {
t time.Time
errinfo string
}
// Task task struct
// Deprecated
type Task struct {
// Deprecated
Taskname string
// Deprecated
Spec *Schedule
// Deprecated
SpecStr string
// Deprecated
DoFunc TaskFunc
// Deprecated
Prev time.Time
// Deprecated
Next time.Time
// Deprecated
Errlist []*taskerr // like errtime:errinfo
// Deprecated
ErrLimit int // max length for the errlist, 0 stand for no limit
delegate *task.Task
}
// NewTask add new task with name, time and func
func NewTask(tname string, spec string, f TaskFunc) *Task {
task := task.NewTask(tname, spec, func(ctx context.Context) error {
return f()
})
return &Task{
delegate: task,
}
}
// GetSpec get spec string
func (t *Task) GetSpec() string {
t.initDelegate()
return t.delegate.GetSpec(context.Background())
}
// GetStatus get current task status
func (t *Task) GetStatus() string {
t.initDelegate()
return t.delegate.GetStatus(context.Background())
}
// Run run all tasks
func (t *Task) Run() error {
t.initDelegate()
return t.delegate.Run(context.Background())
}
// SetNext set next time for this task
func (t *Task) SetNext(now time.Time) {
t.initDelegate()
t.delegate.SetNext(context.Background(), now)
}
// GetNext get the next call time of this task
func (t *Task) GetNext() time.Time {
t.initDelegate()
return t.delegate.GetNext(context.Background())
}
// SetPrev set prev time of this task
func (t *Task) SetPrev(now time.Time) {
t.initDelegate()
t.delegate.SetPrev(context.Background(), now)
}
// GetPrev get prev time of this task
func (t *Task) GetPrev() time.Time {
t.initDelegate()
return t.delegate.GetPrev(context.Background())
}
// six columns mean
// second0-59
// minute0-59
// hour1-23
// day1-31
// month1-12
// week0-60 means Sunday
// SetCron some signals
// * any time
// ,  separate signal
//    duration
// /n : do as n times of time duration
// ///////////////////////////////////////////////////////
// 0/30 * * * * * every 30s
// 0 43 21 * * * 21:43
// 0 15 05 * * *    05:15
// 0 0 17 * * * 17:00
// 0 0 17 * * 1 17:00 in every Monday
// 0 0,10 17 * * 0,2,3 17:00 and 17:10 in every Sunday, Tuesday and Wednesday
// 0 0-10 17 1 * * 17:00 to 17:10 in 1 min duration each time on the first day of month
// 0 0 0 1,15 * 1 0:00 on the 1st day and 15th day of month
// 0 42 4 1 * *     4:42 on the 1st day of month
// 0 0 21 * * 1-6   21:00 from Monday to Saturday
// 0 0,10,20,30,40,50 * * * *  every 10 min duration
// 0 */10 * * * *        every 10 min duration
// 0 * 1 * * *         1:00 to 1:59 in 1 min duration each time
// 0 0 1 * * *         1:00
// 0 0 */1 * * *        0 min of hour in 1 hour duration
// 0 0 * * * *         0 min of hour in 1 hour duration
// 0 2 8-20/3 * * *       8:02, 11:02, 14:02, 17:02, 20:02
// 0 30 5 1,15 * *       5:30 on the 1st day and 15th day of month
func (t *Task) SetCron(spec string) {
t.initDelegate()
t.delegate.SetCron(spec)
}
func (t *Task) initDelegate() {
if t.delegate == nil {
t.delegate = &task.Task{
Taskname: t.Taskname,
Spec: (*task.Schedule)(t.Spec),
SpecStr: t.SpecStr,
DoFunc: func(ctx context.Context) error {
return t.DoFunc()
},
Prev: t.Prev,
Next: t.Next,
ErrLimit: t.ErrLimit,
}
}
}
// Next set schedule to next time
func (s *Schedule) Next(t time.Time) time.Time {
return (*task.Schedule)(s).Next(t)
}
// StartTask start all tasks
func StartTask() {
task.StartTask()
}
// StopTask stop all tasks
func StopTask() {
task.StopTask()
}
// AddTask add task with name
func AddTask(taskname string, t Tasker) {
task.AddTask(taskname, &oldToNewAdapter{delegate: t})
}
// DeleteTask delete task with name
func DeleteTask(taskname string) {
task.DeleteTask(taskname)
}
// ClearTask clear all tasks
func ClearTask() {
task.ClearTask()
}
// MapSorter sort map for tasker
type MapSorter task.MapSorter
// NewMapSorter create new tasker map
func NewMapSorter(m map[string]Tasker) *MapSorter {
newTaskerMap := make(map[string]task.Tasker, len(m))
for key, value := range m {
newTaskerMap[key] = &oldToNewAdapter{
delegate: value,
}
}
return (*MapSorter)(task.NewMapSorter(newTaskerMap))
}
// Sort sort tasker map
func (ms *MapSorter) Sort() {
sort.Sort(ms)
}
func (ms *MapSorter) Len() int { return len(ms.Keys) }
func (ms *MapSorter) Less(i, j int) bool {
if ms.Vals[i].GetNext(context.Background()).IsZero() {
return false
}
if ms.Vals[j].GetNext(context.Background()).IsZero() {
return true
}
return ms.Vals[i].GetNext(context.Background()).Before(ms.Vals[j].GetNext(context.Background()))
}
func (ms *MapSorter) Swap(i, j int) {
ms.Vals[i], ms.Vals[j] = ms.Vals[j], ms.Vals[i]
ms.Keys[i], ms.Keys[j] = ms.Keys[j], ms.Keys[i]
}
func init() {
AdminTaskList = make(map[string]Tasker)
}
type oldToNewAdapter struct {
delegate Tasker
}
func (o *oldToNewAdapter) GetSpec(ctx context.Context) string {
return o.delegate.GetSpec()
}
func (o *oldToNewAdapter) GetStatus(ctx context.Context) string {
return o.delegate.GetStatus()
}
func (o *oldToNewAdapter) Run(ctx context.Context) error {
return o.delegate.Run()
}
func (o *oldToNewAdapter) SetNext(ctx context.Context, t time.Time) {
o.delegate.SetNext(t)
}
func (o *oldToNewAdapter) GetNext(ctx context.Context) time.Time {
return o.delegate.GetNext()
}
func (o *oldToNewAdapter) SetPrev(ctx context.Context, t time.Time) {
o.delegate.SetPrev(t)
}
func (o *oldToNewAdapter) GetPrev(ctx context.Context) time.Time {
return o.delegate.GetPrev()
}