async triggers for either interval or next due, accept cron
parent
c90cbfc7be
commit
0f8637c9ff
|
|
@ -87,37 +87,58 @@ func has(params url.Values, k string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Ajax) Async() {
|
func (a *Ajax) Async() {
|
||||||
|
var err error
|
||||||
|
nextDue := time.Now().Add(config.Loop)
|
||||||
c := time.NewTicker(config.Loop)
|
c := time.NewTicker(config.Loop)
|
||||||
for range c.C {
|
for {
|
||||||
|
select {
|
||||||
|
case <-c.C:
|
||||||
|
case <-time.After(time.Until(nextDue)):
|
||||||
|
}
|
||||||
log.Println("loop tasks")
|
log.Println("loop tasks")
|
||||||
if err := a.loopTasks(); err != nil {
|
nextDue, err = a.loopTasks()
|
||||||
|
if err != nil {
|
||||||
log.Println("failed to loop tasks", err)
|
log.Println("failed to loop tasks", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Ajax) loopTasks() error {
|
func (a *Ajax) loopTasks() (time.Time, error) {
|
||||||
|
nextDue := time.Now().Add(time.Hour * 240)
|
||||||
lists, err := a.storageListLists()
|
lists, err := a.storageListLists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nextDue, err
|
||||||
}
|
}
|
||||||
for _, list := range lists {
|
for _, list := range lists {
|
||||||
tasks, err := a.storageListTasks(list.UUID, func(t *task.Task) bool {
|
tasks, err := a.storageListTasks(list.UUID, func(t *task.Task) bool {
|
||||||
return t.Complete
|
return t.Complete
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nextDue, err
|
||||||
}
|
}
|
||||||
for _, task := range tasks {
|
for _, task := range tasks {
|
||||||
if !task.Complete || task.Loop == 0 || time.Since(task.Completed) < task.Loop {
|
if !task.Complete {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if task.Loop == 0 && task.Cron == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
nextLoopTrigger := task.Completed.Add(task.Loop)
|
||||||
|
if task.Loop == 0 {
|
||||||
|
nextLoopTrigger = task.Cron.Next()
|
||||||
|
}
|
||||||
|
if time.Now().Before(nextLoopTrigger) {
|
||||||
|
if nextLoopTrigger.Before(nextDue) {
|
||||||
|
nextDue = nextLoopTrigger
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
task.Complete = false
|
task.Complete = false
|
||||||
task.Completed = time.Time{}
|
task.Completed = time.Time{}
|
||||||
if err := a.storageSetTask(list.UUID, task); err != nil {
|
if err := a.storageSetTask(list.UUID, task); err != nil {
|
||||||
return err
|
return nextDue, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nextDue, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package form
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/robfig/cron/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cron string
|
||||||
|
|
||||||
|
func (c Cron) Next() time.Time {
|
||||||
|
schedule, err := cron.ParseStandard(string(c))
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
return schedule.Next(time.Now())
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,7 @@ type Task struct {
|
||||||
Note []string
|
Note []string
|
||||||
Due time.Time
|
Due time.Time
|
||||||
Loop time.Duration
|
Loop time.Duration
|
||||||
|
Cron form.Cron
|
||||||
|
|
||||||
Index int
|
Index int
|
||||||
}
|
}
|
||||||
|
|
@ -45,6 +46,7 @@ func New(r *http.Request) (*Task, error) {
|
||||||
Edited: time.Now(),
|
Edited: time.Now(),
|
||||||
Due: form.ToTime(form.Get(r, "duedate")),
|
Due: form.ToTime(form.Get(r, "duedate")),
|
||||||
Loop: form.ToDuration(form.Get(r, "loop")),
|
Loop: form.ToDuration(form.Get(r, "loop")),
|
||||||
|
Cron: form.Cron(form.Get(r, "cron")),
|
||||||
}
|
}
|
||||||
task.SetNote(form.Get(r, "note"))
|
task.SetNote(form.Get(r, "note"))
|
||||||
return task, task.validate()
|
return task, task.validate()
|
||||||
|
|
@ -75,7 +77,8 @@ func (t *Task) MarshalJSON() ([]byte, error) {
|
||||||
// "dueStr":"",
|
// "dueStr":"",
|
||||||
// "dueInt":33330000,
|
// "dueInt":33330000,
|
||||||
// "dueTitle":"Due ",
|
// "dueTitle":"Due ",
|
||||||
// "loop": "1m"}
|
// "loop": "1m",
|
||||||
|
// "cron": "* * * * *"}
|
||||||
// ]}
|
// ]}
|
||||||
fullFormat := "02 Jan 2006 03:04 PM"
|
fullFormat := "02 Jan 2006 03:04 PM"
|
||||||
shortFormat := "02 Jan"
|
shortFormat := "02 Jan"
|
||||||
|
|
@ -112,6 +115,7 @@ func (t *Task) MarshalJSON() ([]byte, error) {
|
||||||
"dueInt": t.Due.Unix(),
|
"dueInt": t.Due.Unix(),
|
||||||
"dueTitle": "Due ",
|
"dueTitle": "Due ",
|
||||||
"loop": t.Loop.String(),
|
"loop": t.Loop.String(),
|
||||||
|
"cron": t.Cron,
|
||||||
}
|
}
|
||||||
if t.Due.IsZero() {
|
if t.Due.IsZero() {
|
||||||
for k := range m {
|
for k := range m {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue