Implement main, optional seconds, and from file
parent
a1cea7d1cb
commit
877ec310bd
4
TODO.md
4
TODO.md
|
|
@ -17,7 +17,9 @@
|
||||||
|
|
||||||
# Backend
|
# Backend
|
||||||
|
|
||||||
1. load from file
|
x load from file
|
||||||
1. interrupt running jobs
|
1. interrupt running jobs
|
||||||
1. temporarily disable jobs
|
1. temporarily disable jobs
|
||||||
1. json API
|
1. json API
|
||||||
|
1. change cron to load the full job from storage so not holding big queued jobs in ram
|
||||||
|
1. add optional second for test main
|
||||||
|
|
|
||||||
15
main.go
15
main.go
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"local/firestormy/config"
|
"local/firestormy/config"
|
||||||
|
"local/firestormy/scheduler"
|
||||||
"local/firestormy/server"
|
"local/firestormy/server"
|
||||||
"local/lastn/lastn"
|
"local/lastn/lastn"
|
||||||
"log"
|
"log"
|
||||||
|
|
@ -13,11 +14,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var err error
|
||||||
|
s := scheduler.New()
|
||||||
|
if config.Config != "" {
|
||||||
|
s, err = scheduler.NewFromFile(config.Config)
|
||||||
|
} else {
|
||||||
|
err = s.Start()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
server := server.New()
|
server := server.New()
|
||||||
if err := server.Routes(); err != nil {
|
if err := server.Routes(); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go EnqueueBackups()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Printf("Serving on %q", config.Port)
|
log.Printf("Serving on %q", config.Port)
|
||||||
if err := http.ListenAndServe(config.Port, server); err != nil {
|
if err := http.ListenAndServe(config.Port, server); err != nil {
|
||||||
|
|
@ -29,6 +43,7 @@ func main() {
|
||||||
stop := make(chan os.Signal)
|
stop := make(chan os.Signal)
|
||||||
signal.Notify(stop, os.Interrupt)
|
signal.Notify(stop, os.Interrupt)
|
||||||
<-stop
|
<-stop
|
||||||
|
s.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func EnqueueBackups() {
|
func EnqueueBackups() {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import cron "github.com/robfig/cron/v3"
|
||||||
|
|
||||||
func getParser() cron.Parser {
|
func getParser() cron.Parser {
|
||||||
return cron.NewParser(
|
return cron.NewParser(
|
||||||
cron.Minute |
|
cron.SecondOptional |
|
||||||
|
cron.Minute |
|
||||||
cron.Hour |
|
cron.Hour |
|
||||||
cron.Dom |
|
cron.Dom |
|
||||||
cron.Month |
|
cron.Month |
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ func TestValidCronFail(t *testing.T) {
|
||||||
cases := []string{
|
cases := []string{
|
||||||
"a 1 1 1 1",
|
"a 1 1 1 1",
|
||||||
"1 1 1 1",
|
"1 1 1 1",
|
||||||
"1 1 1 1 1 1",
|
|
||||||
"@minutely",
|
"@minutely",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,10 +21,12 @@ func TestValidCronPass(t *testing.T) {
|
||||||
"1 1 1 1 1",
|
"1 1 1 1 1",
|
||||||
"* * 1 1 1",
|
"* * 1 1 1",
|
||||||
"@hourly",
|
"@hourly",
|
||||||
|
"1 1 1 1 1 1",
|
||||||
"@daily",
|
"@daily",
|
||||||
"@yearly",
|
"@yearly",
|
||||||
"@weekly",
|
"@weekly",
|
||||||
"* */5 1 1 1",
|
"* */5 1 1 1",
|
||||||
|
"*/5 * */5 1 1 1",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ func New() *Scheduler {
|
||||||
cron.SkipIfStillRunning(l),
|
cron.SkipIfStillRunning(l),
|
||||||
cron.Recover(l),
|
cron.Recover(l),
|
||||||
),
|
),
|
||||||
|
cron.WithParser(getParser()),
|
||||||
)
|
)
|
||||||
return &Scheduler{
|
return &Scheduler{
|
||||||
cron: c,
|
cron: c,
|
||||||
|
|
@ -79,7 +80,7 @@ func cleanLine(b []byte) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitScheduleCommand(b []byte) (string, string) {
|
func splitScheduleCommand(b []byte) (string, string) {
|
||||||
re := regexp.MustCompile(`^((\d+|\*\/\d+|(\d,)*\d+|\*) [ ]*){5}`)
|
re := regexp.MustCompile(`^((\d+|\*\/\d+|(\d,)*\d+|\*) [ ]*){5,6}`)
|
||||||
schedule := string(re.Find(b))
|
schedule := string(re.Find(b))
|
||||||
if len(schedule) == 0 {
|
if len(schedule) == 0 {
|
||||||
return "", ""
|
return "", ""
|
||||||
|
|
@ -150,13 +151,13 @@ func (s *Scheduler) Add(j *Job) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := config.Store.Set(j.Name, b); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
entryID, err := s.cron.AddJob(j.Schedule, j)
|
entryID, err := s.cron.AddJob(j.Schedule, j)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := config.Store.Set(j.Name, b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
s.running[j.Name] = entryID
|
s.running[j.Name] = entryID
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,10 @@ func TestSchedulerFromFile(t *testing.T) {
|
||||||
content: `10 */12 * * * /bin/bash -c "hostname"`,
|
content: `10 */12 * * * /bin/bash -c "hostname"`,
|
||||||
want: 1,
|
want: 1,
|
||||||
},
|
},
|
||||||
|
"just a job with seconds": {
|
||||||
|
content: `*/2 10 */12 * * * /bin/bash -c "hostname"`,
|
||||||
|
want: 1,
|
||||||
|
},
|
||||||
"all wild": {
|
"all wild": {
|
||||||
content: `* * * * * /bin/bash -c "hostname"`,
|
content: `* * * * * /bin/bash -c "hostname"`,
|
||||||
want: 1,
|
want: 1,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
# comment only
|
||||||
Loading…
Reference in New Issue