package main import ( "context" "flag" "fmt" "log" "net" "net/http" "os" "os/signal" "runtime" "runtime/pprof" "syscall" "github.com/caarlos0/env/v10" "source.toby3d.me/toby3d/home/internal/domain" ) var ( config = new(domain.Config) logger = log.New(os.Stdout, "home\t", log.Lmsgprefix|log.LstdFlags|log.LUTC) ) var cpuProfilePath, memProfilePath string func init() { flag.StringVar(&cpuProfilePath, "cpuprofile", "", "set path to saving CPU memory profile") flag.StringVar(&memProfilePath, "memprofile", "", "set path to saving pprof memory profile") flag.Parse() if err := env.ParseWithOptions(config, env.Options{ Prefix: "HOME_", }); err != nil { logger.Fatalln("cannot unmarshal configuration into domain:", err) } } func main() { ctx := context.Background() server := &http.Server{ Addr: config.AddrPort().String(), Handler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { fmt.Fprintln(w, "hello, world!") }), ErrorLog: logger, BaseContext: func(ln net.Listener) context.Context { return ctx }, } done := make(chan os.Signal, 1) signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) if cpuProfilePath != "" { cpuProfile, err := os.Create(cpuProfilePath) if err != nil { logger.Fatalln("could not create CPU profile:", err) } defer cpuProfile.Close() if err = pprof.StartCPUProfile(cpuProfile); err != nil { logger.Fatalln("could not start CPU profile:", err) } defer pprof.StopCPUProfile() } go func(server *http.Server) { logger.Printf("starting server on %d...", config.Port) if err := server.ListenAndServe(); err != nil { logger.Fatalln("cannot listen and serve server:", err) } }(server) <-done if err := server.Shutdown(ctx); err != nil { logger.Fatalln("failed shutdown server:", err) } if memProfilePath == "" { return } memProfile, err := os.Create(memProfilePath) if err != nil { logger.Fatalln("could not create memory profile:", err) } defer memProfile.Close() runtime.GC() // NOTE(toby3d): get up-to-date statistics if err = pprof.WriteHeapProfile(memProfile); err != nil { logger.Fatalln("could not write memory profile:", err) } }