From 0188cd0b84412e23ecbb489121bbf742ec5a6134 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 6 Aug 2016 23:53:10 -0700 Subject: [PATCH] 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 --- main.go | 2 +- utils.go | 13 ++++++++----- utils_test.go | 20 +++++++++----------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/main.go b/main.go index b8f949eda..83e6df11d 100644 --- a/main.go +++ b/main.go @@ -191,7 +191,7 @@ func main() { // Initialize and monitor shutdown signal shutdownSignal = make(chan bool, 1) - monitorShutdownSignal() + monitorShutdownSignal(os.Exit) // Run the app - exit on error. app.RunAndExitOnError() diff --git a/utils.go b/utils.go index 579ad409b..5e8aacf0d 100644 --- a/utils.go +++ b/utils.go @@ -100,10 +100,13 @@ func registerObjectStorageShutdown(callback func() errCode) { 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 -func monitorShutdownSignal() { +func monitorShutdownSignal(onExitFn onExitFunc) { go func() { - // Monitor processus signal + // Monitor signals. trapCh := signalTrap(os.Interrupt, syscall.SIGTERM) for { select { @@ -115,7 +118,7 @@ func monitorShutdownSignal() { for _, callback := range shutdownCallbacks { exitCode := callback() if exitCode != exitSuccess { - os.Exit(int(exitCode)) + onExitFn(int(exitCode)) } } @@ -123,11 +126,11 @@ func monitorShutdownSignal() { for _, callback := range shutdownObjectStorageCallbacks { exitCode := callback() if exitCode != exitSuccess { - os.Exit(int(exitCode)) + onExitFn(int(exitCode)) } } - os.Exit(int(exitSuccess)) + onExitFn(int(exitSuccess)) } } }() diff --git a/utils_test.go b/utils_test.go index 62d7f7d34..76a5ed318 100644 --- a/utils_test.go +++ b/utils_test.go @@ -16,13 +16,10 @@ package main -import ( - "testing" -) +import "testing" -// ShutdownCallback simulates a successful exit here, all registered -// shutdown callbacks need to return exitSuccess for this test to succeed -func TestShutdownCallback(t *testing.T) { +// ShutdownCallback simulates a successful and failure exit here. +func TestShutdownCallbackSuccess(t *testing.T) { // Register two callbacks that return success registerObjectStorageShutdown(func() errCode { return exitSuccess @@ -33,10 +30,11 @@ func TestShutdownCallback(t *testing.T) { shutdownSignal = make(chan bool, 1) shutdownSignal <- true - // Start executing callbacks and quit if everything is fine - monitorShutdownSignal() - - // Infinite loop here simulates an infinite running program - for { + // Start executing callbacks and exitFunc receives a success. + dummySuccess := func(code int) { + if code != int(exitSuccess) { + t.Fatalf("Expected %d, got %d instead.", code, exitSuccess) + } } + monitorShutdownSignal(dummySuccess) }