util-go/time/scheduler/task/task.go

80 lines
1.9 KiB
Go
Raw Normal View History

2018-04-28 12:39:55 +00:00
package task
import (
"crypto/sha1"
"fmt"
"io"
"reflect"
"time"
)
type TaskSchedule struct {
IsRecurring bool
LastRun time.Time
NextRun time.Time
Duration time.Duration
}
type Task struct {
*TaskSchedule
TaskTarget *TaskTarget
Params []interface{}
}
// New returns an instance of task
func New(taskTarget *TaskTarget, params []interface{}) *Task {
return &Task{
TaskSchedule: &TaskSchedule{},
TaskTarget: taskTarget,
Params: params,
}
}
// NewWithSchedule creates an instance of task with the provided schedule information
func NewWithSchedule(taskTarget *TaskTarget, params []interface{}, taskSchedule *TaskSchedule) *Task {
return &Task{
TaskSchedule: taskSchedule,
TaskTarget: taskTarget,
Params: params,
}
}
// IsDue returns a boolean indicating whether the task should execute or not
func (t *Task) IsDue() bool {
timeNow := time.Now()
return timeNow == t.NextRun || timeNow.After(t.NextRun)
}
// Run will execute the task and schedule it's next run.
func (t *Task) Run() {
// Reschedule task first to prevent running the task
// again in case the execution time takes more than the
// task's duration value.
t.scheduleNextRun()
fv := reflect.ValueOf(t.TaskTarget.targetFunc)
params := make([]reflect.Value, len(t.Params))
for i, param := range t.Params {
params[i] = reflect.ValueOf(param)
}
fv.Call(params)
}
// Hash will return the SHA1 representation of the task's data.
func (t *Task) Hash() string {
hash := sha1.New()
_, _ = io.WriteString(hash, t.TaskTarget.Name)
_, _ = io.WriteString(hash, fmt.Sprintf("%+v", t.Params))
_, _ = io.WriteString(hash, fmt.Sprintf("%s", t.TaskSchedule.Duration))
_, _ = io.WriteString(hash, fmt.Sprintf("%t", t.TaskSchedule.IsRecurring))
return fmt.Sprintf("%x", hash.Sum(nil))
}
func (t *Task) scheduleNextRun() {
if !t.IsRecurring {
return
}
t.LastRun = t.NextRun
t.NextRun = t.NextRun.Add(t.Duration)
}