package main import ( "fmt" "log" "os" "os/signal" "syscall" "github.com/gliderlabs/ssh" ) var ( metricsNumPasswords int metricsCityNum map[string]int cities map[string]location ) func main() { // create a map mapping a city to an amount of hits metricsCityNum = make(map[string]int) // create a cities map mapping a city to a location cities = make(map[string]location) // parse flags building a config struct config := parseFlags() // if a state exists, load it err := loadState(config) if err != nil { log.Printf("Could not load the state: %s", err) } // start the ssh server log.Printf("Starting SSH listener on port %d", config.sshPort) go func() { sshPortString := fmt.Sprintf(":%d", config.sshPort) listenErr := ssh.ListenAndServe(sshPortString, nil, ssh.PasswordAuth(handlePass)) if listenErr != nil { log.Fatalln(listenErr.Error()) } }() // Start the exit handler handing SIGTERM syscalls // The handler writes the state (the amount of hits processed until the // syscall) to the statefile exitHandler(config) // start the http server exposing the metrics // this is blocking setupHTTPServer(config) } func exitHandler(config config) { // relay incoming signals to the signalChannel signalChannel := make(chan os.Signal, 2) signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) // wait until a signal is given, then write the state to a file, THEN exit go func() { <-signalChannel fmt.Println("Ending process... Saving the state") // write the state to a file err := WriteStateToFile(config) if err != nil { log.Printf("Error writing the stateFile: %s", err) } os.Exit(0) }() }