A utility to execute given functions when the configured signal(s) fire.
Functions are executed in LIFO order just like defer statements.
The default behavior is designed to facilitate executing function(s) on application termination.
Usage Example: go-rest-api-example
In the below example, methods closeDBConnection and notifyServiceX will never be executed if the service is terminated.
Try it yourself, run the below code and try to kill it using Ctrl+C.
package main
import (
"fmt"
"net/http"
)
func main() {
fmt.Println("In main")
defer closeDBConnection()
defer notifyServiceX()
http.ListenAndServe(":8090", nil)
}
func closeDBConnection() {
fmt.Println("Closing DB Connection")
}
func notifyServiceX() {
fmt.Println("Hey Service X, I (Service A) am terminating.")
}In main
^CWith the below code, you can be assured that whatever logic you want to run on your service termination, it will always be executed.
package main
import (
"fmt"
"net/http"
"github.com/rameshsunkara/deferrun"
)
func main() {
fmt.Println("In main")
r := deferrun.NewSignalHandler()
r.OnSignal(closeDBConnection)
r.OnSignal(notifyServiceX)
http.ListenAndServe(":8090", nil)
}
func closeDBConnection() {
fmt.Println("Closing DB Connection")
}
func notifyServiceX() {
fmt.Println("Hey Service X, I (Service A) am terminating.")
}In main
^CHey Service X, I (Service A) am terminating.
Closing DB ConnectionBy default, it listens for following signals:
os.Interrupt, syscall.SIGTERM, syscall.SIGINT
If you want to customize the Signals you want to listen, simply pass whichever signals you want:
r := deferrun.NewSignalHandler(syscall.SIGINT, syscall.SIGABRT)By design, OnSignal accepts only functions with no parameters or return values as handling the return value should be consumers responsibility and not something that can be generalized.
If the method you want to execute has parameters or return values simply wrap it and then use OnSignal.
For example, say closeDBConnection can return a error. So wrap closeDBConnection in no-arg, no-return value function and pass it to OnSignal.
package main
import (
"fmt"
"net/http"
"github.com/rameshsunkara/deferrun"
)
func main() {
fmt.Println("In main")
r := deferrun.NewSignalHandler()
r.OnSignal(func() {
if err := closeDBConnection(); err!= nil {
fmt.Println("Too bad, notify everyone as it can cause havoc")
}
})
http.ListenAndServe(":8090", nil)
}
func closeDBConnection() error {
fmt.Println("Closing DB Connection")
return nil
}make helpTo get your setup up and running the only thing you have to do is
make allRun linting
make lintRun tests
make test