diff --git a/README.md b/README.md index b051c42..27522b8 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,9 @@ Gron provides a clear syntax for writing and deploying cron jobs. ## Different to origin -Most features and interfaces are as same as origin repository, but also introduces one new method to Cron, which `StopAfterJobDone` make cron has ability to hold the process, stop creating new child goroutine, and ensure sub-job is finished before main goroutine close. This benefit to the scenarios like handling `os.Signal` including `SIGINT`, `SIGTERM` (which handler does not including in library). After interrupt signal handling, stopping cron gracefully via `StopAfterJobDone`, prevent bundle of processing job stop inappropriately. +Most features and interfaces are as same as origin repository, but also introduces one new feature to Cron, which `GracefullyStop()` make cron has ability to hold the process, stop creating new child goroutine, and ensure sub-job is finished before main goroutine close. This benefit to the scenarios like handling `os.Signal` including `SIGINT`, `SIGTERM` (which handler does not including in library). After interrupt signal handling, stopping cron gracefully via `GracefullyStop`, prevent bundle of processing job stop inappropriately. + +Second new feature is built in OS signal handler, after calling `HandleSignals()`, and passing target signal, Cron would register signals, while signals interrupt, it's behavior would just like `GracefullyStop()` (which also means not exactly same) that ensure sub-job are finished. ## Installation @@ -120,6 +122,20 @@ In `gron`, the interface value `Schedule` has the following concrete types: For more info, checkout `schedule.go`. +### Serve like a server + +In real case, you may need a infinite `for` loop to keep main goroutine alive, in fact, you can use `StartAndServe()` to do that. + +`StartAndServe()` is the method to start cron and keeping process there like a server. + +```go +c := gron.New() +c.AddFunc(gron.Every(1*time.Second), func() { + fmt.Println("runs every second") +}) +c.StartAndServe() +``` + ### Full Example ```go diff --git a/cron.go b/cron.go index ada7dab..fe47da1 100644 --- a/cron.go +++ b/cron.go @@ -1,6 +1,8 @@ package gron import ( + "errors" + "fmt" "os" "os/signal" "sort" @@ -83,6 +85,12 @@ func (c *Cron) HandleSignals(signals ...os.Signal) { signal.Notify(c.sigChan, signals...) } +// StartAndServe serve cron like a eternal process +func (c *Cron) StartAndServe() error { + c.running = true + return c.run() +} + // Start signals cron instant c to get up and running. func (c *Cron) Start() { c.running = true @@ -143,7 +151,7 @@ var after = time.After // // It needs to be private as it's responsible of synchronizing a critical // shared state: `running`. -func (c *Cron) run() { +func (c *Cron) run() error { var effective time.Time now := time.Now().Local() @@ -173,14 +181,14 @@ func (c *Cron) run() { c.wg.Add(1) go entry.Job.Run(&c.wg) } - case <-c.sigChan: + case sig := <-c.sigChan: c.stopAndWait() - return + return fmt.Errorf("Interrupt by signal: %s", sig) case e := <-c.add: e.Next = e.Schedule.Next(time.Now()) c.entries = append(c.entries, e) case <-c.stop: - return // terminate go-routine. + return errors.New("Cron stop") // terminate go-routine. } } }