utils: Take monitorShutdownSignal to take an exitFunc which would executed upon error. (#2378)

This hook approach allows program to keep running but being able to handle exiting
of the program in the dynamic way.

Fixes #2377
master
Harshavardhana 8 years ago committed by GitHub
parent b23605a2b5
commit 0188cd0b84
  1. 2
      main.go
  2. 13
      utils.go
  3. 20
      utils_test.go

@ -191,7 +191,7 @@ func main() {
// Initialize and monitor shutdown signal // Initialize and monitor shutdown signal
shutdownSignal = make(chan bool, 1) shutdownSignal = make(chan bool, 1)
monitorShutdownSignal() monitorShutdownSignal(os.Exit)
// Run the app - exit on error. // Run the app - exit on error.
app.RunAndExitOnError() app.RunAndExitOnError()

@ -100,10 +100,13 @@ func registerObjectStorageShutdown(callback func() errCode) {
shutdownObjectStorageCallbacks = append(shutdownObjectStorageCallbacks, callback) shutdownObjectStorageCallbacks = append(shutdownObjectStorageCallbacks, callback)
} }
// Represents a type of an exit func which will be invoked during shutdown signal.
type onExitFunc func(code int)
// Start to monitor shutdownSignal to execute shutdown callbacks // Start to monitor shutdownSignal to execute shutdown callbacks
func monitorShutdownSignal() { func monitorShutdownSignal(onExitFn onExitFunc) {
go func() { go func() {
// Monitor processus signal // Monitor signals.
trapCh := signalTrap(os.Interrupt, syscall.SIGTERM) trapCh := signalTrap(os.Interrupt, syscall.SIGTERM)
for { for {
select { select {
@ -115,7 +118,7 @@ func monitorShutdownSignal() {
for _, callback := range shutdownCallbacks { for _, callback := range shutdownCallbacks {
exitCode := callback() exitCode := callback()
if exitCode != exitSuccess { if exitCode != exitSuccess {
os.Exit(int(exitCode)) onExitFn(int(exitCode))
} }
} }
@ -123,11 +126,11 @@ func monitorShutdownSignal() {
for _, callback := range shutdownObjectStorageCallbacks { for _, callback := range shutdownObjectStorageCallbacks {
exitCode := callback() exitCode := callback()
if exitCode != exitSuccess { if exitCode != exitSuccess {
os.Exit(int(exitCode)) onExitFn(int(exitCode))
} }
} }
os.Exit(int(exitSuccess)) onExitFn(int(exitSuccess))
} }
} }
}() }()

@ -16,13 +16,10 @@
package main package main
import ( import "testing"
"testing"
)
// ShutdownCallback simulates a successful exit here, all registered // ShutdownCallback simulates a successful and failure exit here.
// shutdown callbacks need to return exitSuccess for this test to succeed func TestShutdownCallbackSuccess(t *testing.T) {
func TestShutdownCallback(t *testing.T) {
// Register two callbacks that return success // Register two callbacks that return success
registerObjectStorageShutdown(func() errCode { registerObjectStorageShutdown(func() errCode {
return exitSuccess return exitSuccess
@ -33,10 +30,11 @@ func TestShutdownCallback(t *testing.T) {
shutdownSignal = make(chan bool, 1) shutdownSignal = make(chan bool, 1)
shutdownSignal <- true shutdownSignal <- true
// Start executing callbacks and quit if everything is fine // Start executing callbacks and exitFunc receives a success.
monitorShutdownSignal() dummySuccess := func(code int) {
if code != int(exitSuccess) {
// Infinite loop here simulates an infinite running program t.Fatalf("Expected %d, got %d instead.", code, exitSuccess)
for { }
} }
monitorShutdownSignal(dummySuccess)
} }

Loading…
Cancel
Save