Skip to content

Commit

Permalink
Little bit of refactoring to make code cleaner and silence vet -shadow.
Browse files Browse the repository at this point in the history
  • Loading branch information
lunemec committed Sep 20, 2018
1 parent 7130b5d commit a192d86
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -38,7 +38,7 @@ vet:
go vet ./...

lint:
gometalinter.v2 --disable=vetshadow --vendor ./...
gometalinter.v2 --deadline 120s --vendor ./...

clean:
rm nanny || true
Expand Down
32 changes: 17 additions & 15 deletions api/api.go
Expand Up @@ -9,6 +9,7 @@ import (
"strconv"
"time"

"nanny/pkg/closer"
"nanny/pkg/nanny"
"nanny/pkg/notifier"
"nanny/pkg/storage"
Expand Down Expand Up @@ -97,6 +98,8 @@ func loadStorage(n *nanny.Nanny, notifiers notifiers, store storage.Storage) {
log.Warn(msg)
return
}
// create callback func using our storage.
callbackFunc := makeCallbackFunc(store)

// Create nanny timers from persisted signals.
for _, signal := range signals {
Expand Down Expand Up @@ -124,12 +127,7 @@ func loadStorage(n *nanny.Nanny, notifiers notifiers, store storage.Storage) {
NextSignal: time.Until(signal.NextSignal),
Meta: signal.Meta,

CallbackFunc: func(s *nanny.Signal) {
err := store.Remove(storage.Signal{Name: s.Name})
if err != nil {
log.Error("Error removing signal from storage.", "err", err, "signal", signal)
}
},
CallbackFunc: callbackFunc,
}

err = n.Handle(s)
Expand All @@ -147,6 +145,18 @@ func loadStorage(n *nanny.Nanny, notifiers notifiers, store storage.Storage) {
}
}

// makeCallbackFunc creates new function that can be used as nanny.Signal callback
// while injecting storage dependency. This is used to remove signal from persistent
// storage.
func makeCallbackFunc(store storage.Storage) func(*nanny.Signal) {
return func(signal *nanny.Signal) {
err := store.Remove(storage.Signal{Name: signal.Name})
if err != nil {
log.Error("Error removing signal from storage.", "err", err, "signal", signal)
}
}
}

func router(nanny *nanny.Nanny, notifiers notifiers, store storage.Storage) *mux.Router {
router := mux.NewRouter()
// Clarify this is API.
Expand Down Expand Up @@ -194,7 +204,7 @@ func signalHandler(n *nanny.Nanny, notifiers notifiers, store storage.Storage, w
var signal Signal

dec := json.NewDecoder(req.Body)
defer Close(req.Body)
defer closer.Close(req.Body)

err := dec.Decode(&signal)
if err != nil {
Expand Down Expand Up @@ -321,11 +331,3 @@ func saveRoutes(route *mux.Route, router *mux.Router, ancestors []*mux.Route) er
routes[path] = route.GetName()
return nil
}

// Close closes any io.Closer and checks for error, which will be logged.
func Close(closer io.Closer) {
err := closer.Close()
if err != nil {
log.Error("Unable to close resource!", "err", err, "type", fmt.Sprintf("%T", closer))
}
}
39 changes: 20 additions & 19 deletions cmd/root.go
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"nanny/api"
"nanny/pkg/closer"
"nanny/pkg/notifier"

log "github.com/mgutz/logxi"
Expand Down Expand Up @@ -139,12 +140,8 @@ func runAPI() {
if err != nil {
log.Fatal("Unable to create/load sqlite storage", "dsn", config.StorageDSN, "err", err)
}
defer func() {
err := store.Close()
if err != nil {
log.Fatal("Unable to close sqlite storage.")
}
}()
defer closer.Close(store)

api := api.Server{
Name: config.Name,
Notifiers: notifiers,
Expand All @@ -169,19 +166,7 @@ func runAPI() {

// CTRL+C handling.
idleConnsClosed := make(chan struct{})
go func() {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt)
<-sigint
log.Info("Nanny shutting down.")

// We received an interrupt signal, shut down.
if err := server.Shutdown(context.Background()); err != nil {
// Error from closing listeners, or context timeout:
log.Error("HTTP server Shutdown: %v", err)
}
close(idleConnsClosed)
}()
go shutdown(&server, idleConnsClosed)

log.Info("Nanny listening", "addr", server.Addr)
err = server.ListenAndServe()
Expand Down Expand Up @@ -236,6 +221,22 @@ func makeNotifiers() (map[string]notifier.Notifier, error) {
return notifiers, nil
}

// shutdown handles interrupt signal and shuts down server cleanly, waiting for
// all idle connections to be closed.
func shutdown(server *http.Server, idleConnsClosed chan struct{}) {
sigint := make(chan os.Signal, 1)
signal.Notify(sigint, os.Interrupt)
<-sigint
log.Info("Nanny shutting down.")

// We received an interrupt signal, shut down.
if err := server.Shutdown(context.Background()); err != nil {
// Error from closing listeners, or context timeout:
log.Error("HTTP server Shutdown: %v", err)
}
close(idleConnsClosed)
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
Expand Down
16 changes: 16 additions & 0 deletions pkg/closer/closer.go
@@ -0,0 +1,16 @@
package closer

import (
"fmt"
"io"

log "github.com/mgutz/logxi"
)

// Close closes any io.Closer and checks for error, which will be logged.
func Close(closer io.Closer) {
err := closer.Close()
if err != nil {
log.Error("Unable to close resource!", "err", err, "type", fmt.Sprintf("%T", closer))
}
}

0 comments on commit a192d86

Please sign in to comment.