https://github.com/beiping96/grace
Grace manages long-running goroutines gracefully.
https://github.com/beiping96/grace
context go golang goroutine grace graceful graceful-shutdown graceful-stop gracefully signal signals
Last synced: 4 months ago
JSON representation
Grace manages long-running goroutines gracefully.
- Host: GitHub
- URL: https://github.com/beiping96/grace
- Owner: beiping96
- License: mit
- Created: 2019-05-15T04:01:58.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2020-05-22T10:33:28.000Z (about 6 years ago)
- Last Synced: 2023-07-27T21:57:10.414Z (almost 3 years ago)
- Topics: context, go, golang, goroutine, grace, graceful, graceful-shutdown, graceful-stop, gracefully, signal, signals
- Language: Go
- Homepage:
- Size: 30.3 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Grace
[](https://travis-ci.com/beiping96/grace)
[](https://pkg.go.dev/github.com/beiping96/grace)
[](https://goreportcard.com/report/github.com/beiping96/grace)
[](https://github.com/beiping96/grace/actions)
Grace manages long-running goroutines gracefully by trapping system signals and canceling `context.Context`.
`import "github.com/beiping96/grace"`
The core of Grace is `type Goroutine func(ctx context.Context)`.
## Usage
### Simple
```go
package main
import(
"context"
"time"
"github.com/beiping96/grace"
)
func main() {
// Register worker
grace.Go(worker)
// Start worker and hold main goroutine.
// After process received system signal,
// worker should exit in two seconds,
// otherwise, be killed.
grace.Run(time.Second * time.Duration(2))
}
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
// receive stop signal
return
default:
}
// do some job costs second
time.Sleep(time.Second)
}
}
```
### Pub/Sub
```go
package main
import(
"context"
"time"
"github.com/beiping96/grace"
)
func main() {
// Register puber
grace.Go(puber)
// Register 2 suber
for i := 0; i < 2; i++ {
grace.Go(suber)
}
grace.Run(time.Second) // start
}
var (
jobChan = make(chan struct{}, 1)
)
func puber(ctx context.Context) {
for {
select {
case <-ctx.Done():
// receive stop signal
close(jobChan)
return
default:
}
// load job
var (
job struct{}
)
// pub job
jobChan <- job
}
}
func suber(ctx context.Context) {
for job := range jobChan {
// handle job
println(job)
}
}
```
### HTTPD
```go
package main
import (
"context"
"net/http"
"time"
"github.com/beiping96/grace"
)
func httpd(ctx context.Context) {
server := &http.Server{}
grace.Go(func(ctx context.Context) {
<-ctx.Done()
server.Shutdown(context.Background())
})
server.ListenAndServe()
}
func main() {
// Register httpd
grace.Go(httpd)
// Start
// After process received system signal,
// wait all http connection closed is ten seconds
grace.Run(time.Second * time.Duration(10))
}
```
### Option
```go
package main
import (
"context"
"time"
"github.com/beiping96/grace"
)
func main() {
// After one minute, the worker's ctx will be canceled
grace.Go(worker, grace.OptionExpire(time.Minute))
// If worker stopped, it will be restart
// The max number of restart is 2
grace.Go(worker, grace.OptionRestart(2))
// If worker stopped, it will be restart
// The max number of restart is 2
// Each worker can executed one minute
grace.Go(worker, grace.OptionRestart(2),
grace.OptionExpire(time.Minute))
// If worker stopped, it will be restart
// The max number of restart is 2
// All workers only have one minute to executed
grace.Go(worker, grace.OptionExpire(time.Minute),
grace.OptionRestart(2))
grace.Run(time.Second)
}
func worker(ctx context.Context) {}
```
### Custom
``` go
package main
import (
"log"
"context"
"syscall"
"time"
"github.com/beiping96/grace"
)
func main() {
// Declare stop signals
// Default is syscall.SIGINT, syscall.SIGQUIT or syscall.SIGTERM
grace.Signal(syscall.SIGQUIT, syscall.SIGTERM)
// Declare logger method
// Default is os.Stdout
grace.Log(log.Printf)
// Declare process id folder
// Default is unable
grace.PID("./")
// Register goroutine
grace.Go(worker)
// Register dynamic goroutine
grace.Go(func(ctx context.Context) { grace.Go(worker) })
// Never return
// Stopped when receiving stop signal
// or all goroutines are exit
grace.Run(time.Second)
}
func worker(ctx context.Context) {}
```