Gracefully shutdown server

Listen for SIGINT and SIGTERM signals and write the current state to the
key-value store before shutting down.
This commit is contained in:
William Carroll 2020-02-09 13:53:06 +00:00
parent 0f914d8aa0
commit aba0cd7b9d

View file

@ -17,6 +17,8 @@ import (
"os" "os"
"time" "time"
"kv" "kv"
"os/signal"
"syscall"
) )
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -118,6 +120,34 @@ func refreshTokens(refreshToken string) (string, string) {
return payload.AccessToken, payload.RefreshToken return payload.AccessToken, payload.RefreshToken
} }
// Listen for SIGINT and SIGTERM signals. When received, persist the access and
// refresh tokens and shutdown the server.
func handleInterrupts() {
// Gracefully handle interruptions.
sigs := make(chan os.Signal)
done := make(chan bool)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
log.Printf("Received signal to shutdown. %v\n", sig)
// Persist existing tokens
log.Println("Persisting existing credentials...")
msg := readMsg{make(chan state)}
chans.reads <- msg
state := <-msg.sender
kv.Set("monzoAccessToken", state.accessToken)
kv.Set("monzoRefreshToken", state.refreshToken)
log.Println("Credentials persisted.")
done <- true
}()
<-done
log.Println("Received signal to shutdown. Exiting...")
os.Exit(0)
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Main // Main
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -135,6 +165,9 @@ func main() {
log.Fatal("Cannot start server without access or refresh tokens.") log.Fatal("Cannot start server without access or refresh tokens.")
} }
// Gracefully shutdown.
go handleInterrupts()
// Manage application state. // Manage application state.
go func() { go func() {
state := &state{accessToken, refreshToken} state := &state{accessToken, refreshToken}