Implement main, optional seconds, and from file

master
bel 2020-03-13 04:40:02 +00:00
parent a1cea7d1cb
commit 877ec310bd
7 changed files with 32 additions and 7 deletions

View File

@ -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
View File

@ -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() {

View File

@ -4,6 +4,7 @@ import cron "github.com/robfig/cron/v3"
func getParser() cron.Parser { func getParser() cron.Parser {
return cron.NewParser( return cron.NewParser(
cron.SecondOptional |
cron.Minute | cron.Minute |
cron.Hour | cron.Hour |
cron.Dom | cron.Dom |

View File

@ -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 {

View File

@ -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
} }

View File

@ -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,

1
testdata/comment_only.cron vendored Normal file
View File

@ -0,0 +1 @@
# comment only