// Wait subscribes iteself to few signals and waits for any of them to be received. // When Wait returns it is the end of the application. func (a *Application) Wait() error { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGTERM) for sig := range signalChan { if sig == syscall.SIGHUP { newConfig, err := config.Get() if err != nil { a.logger.Logf("Gettin new config error: %s", err) continue } err = a.Reload(newConfig) if err != nil { a.logger.Logf("Reloading failed: %s", err) } } else { a.logger.Logf("Stopping %d: %s", os.Getpid(), sig) break } } if err := a.Stop(); err != nil { return err } return nil }
//!TODO: implement some "unit" tests for this :) func run() int { if cpuprofile != "" { f, err := os.Create(cpuprofile) if err != nil { fmt.Fprintf(os.Stderr, "Could not create cpuprofile file: %s\n", err) return 1 } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } if showVersion { fmt.Printf("nedomi version %s\n", Version) return 0 } cfg, err := config.Get() if err != nil { fmt.Fprintf(os.Stderr, "Error parsing config: %s\n", err) return 2 } if testConfig { return 0 } //!TODO: simplify and encapsulate application startup: // Move/encapsulate SetupEnv/CleanupEnv, New, Start, Wait, etc. // Leave only something like return App.Run(cfg) // This will possibly simplify configuration reloading and higher contexts as well defer app.CleanupEnv(cfg) if err := app.SetupEnv(cfg); err != nil { fmt.Fprintf(os.Stderr, "Could setup nedomi environment: %s\n", err) return 3 } appInstance, err := app.New(cfg) if err != nil { fmt.Fprintf(os.Stderr, "Could initialize nedomi: %s\n", err) return 4 } if err := appInstance.Start(); err != nil { fmt.Fprintf(os.Stderr, "Could start nedomi: %s\n", err) return 5 } if err := appInstance.Wait(); err != nil { fmt.Fprintf(os.Stderr, "Error stopping the app : %s\n", err) return 6 } return 0 }