Example #1
0
func TrapCloser(cl io.Closer, cleanups ...Cleanup) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGHUP)

	go func() {
		for {
			rawSig := <-c
			sig, ok := rawSig.(syscall.Signal)

			if !ok {
				log.Fatal("not a unix signal")
			}

			switch {
			case sig == syscall.SIGHUP:
				log.Print("SIGHUP: restart process")
				err := RestartProcess()

				if err != nil {
					log.Fatal("failed to restart: " + err.Error())
				}
			case sig == syscall.SIGINT || sig == syscall.SIGKILL || sig == syscall.SIGTERM:
				log.Print("shutting down")
				donec := make(chan bool)
				go func() {
					for _, cb := range cleanups {
						if err := cb(); err != nil {
							log.Error(err)
						}
					}

					if err := cl.Close(); err != nil {
						log.Fatalf("Error shutting down: %v", err)
					}

					donec <- true
				}()
				select {
				case <-donec:
					log.Printf("shutdown")
					os.Exit(0)
				case <-time.After(5 * time.Second):
					log.Fatal("Timeout shutting down. Exiting uncleanly.")
				}
			default:
				log.Fatal("Received another signal, should not happen.")
			}
		}
	}()
}
Example #2
0
func ListenAndServe(conf *config.Config) error {
	setupServer(conf)

	l, err := net.Listen("tcp", conf.Listen)

	if err != nil {
		return err
	}

	log.Printf("Listen on %s", l.Addr())

	sig.TrapCloser(l)
	err = http.Serve(l, nil)
	log.Print("Shutting down ..")
	return err
}