Skip to content

Commit

Permalink
Merge pull request #12 from Fred07/feature/serve-cron-like-server
Browse files Browse the repository at this point in the history
Add StartAndServe() method and update readme
  • Loading branch information
Fred07 authored Mar 18, 2020
2 parents abd3e3e + 7194fc2 commit 619d781
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
16 changes: 12 additions & 4 deletions cron.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package gron

import (
"errors"
"fmt"
"os"
"os/signal"
"sort"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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.
}
}
}
Expand Down

0 comments on commit 619d781

Please sign in to comment.