Skip to content

Commit

Permalink
Added a flag to turn on synchronous job running. If a job is already …
Browse files Browse the repository at this point in the history
…running, then don't run another one. By default this is turned off, so jobs will run in parallel if run time of a job is longer than the schedule period e.g. the job runs for 5 seconds, but the schedule is to run the job every 1 second
  • Loading branch information
Joshua Morris committed Nov 21, 2015
1 parent 139458c commit 9d08217
Showing 1 changed file with 54 additions and 11 deletions.
65 changes: 54 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import (
"os/exec"
"os/signal"
"strings"
"sync"
"syscall"
"time"

"github.com/codegangsta/cli"
"github.com/robfig/cron"
)

var running bool
var mu = &sync.Mutex{}

func main() {
app := cli.NewApp()
app.Name = "docker-cron"
Expand Down Expand Up @@ -84,6 +88,11 @@ SOFTWARE.
Usage: "day of week: 0-6 or SUN-SAT",
EnvVar: "DC_DOW",
},
cli.BoolFlag{
Name: "sync-jobs",
Usage: "should the jobs be run one at a time (true), or whenever they are scheduled",
EnvVar: "DC_SYNC",
},
}
app.Action = func(con *cli.Context) {
// Vars
Expand Down Expand Up @@ -118,21 +127,29 @@ SOFTWARE.
}, " ")
log.Printf("Setup cron to run on schedule: %s\n", schedule)
c.AddFunc(schedule, func() {
log.Printf("Running cron on schedule: %s\n", schedule)
// Run one at a time, syncFlag=true, or whenever scheduled
syncFlag := con.Bool("sync-jobs")
if runJob(syncFlag) {
defer jobDone(syncFlag)

cmd := exec.Command("sh", "-c", command)
log.Printf("Running cron on schedule: %s\n", schedule)

setupStdout(cmd)
setupStderr(cmd)
cmd := exec.Command("sh", "-c", command)

err := cmd.Start()
if err != nil {
log.Fatal("Error running command", err)
}
setupStdout(cmd)
setupStderr(cmd)

err = cmd.Wait()
if err != nil {
log.Fatal("Error waiting for command", err)
err := cmd.Start()
if err != nil {
log.Fatal("Error running command", err)
}

err = cmd.Wait()
if err != nil {
log.Fatal("Error waiting for command", err)
}
} else {
log.Println("A job is already running. The sync-jobs flag is true so we only run one at a time")
}
})
c.Start()
Expand Down Expand Up @@ -172,5 +189,31 @@ func setupStderr(cmd *exec.Cmd) {
log.Printf("ERR: %s\n", scanner.Text())
}
}()
}

// Should we run a job. If syncFlag is false, then we always run a job even if
// there is already one running. If syncFlag is true, then we only run a job
// if one is not already running
func runJob(syncFlag bool) bool {
if syncFlag {
mu.Lock()
defer mu.Unlock()
if running {
return false
} else {
running = true
return true
}
}
// Always run, even if there is already one running
return true
}

func jobDone(syncFlag bool) {
// We only need to change the running state if we have syncrhonous job runs
if syncFlag {
mu.Lock()
defer mu.Unlock()
running = false
}
}

0 comments on commit 9d08217

Please sign in to comment.