package main import ( "context" "fmt" "net/http" "os/signal" "syscall" ) func main() { ctx, can := signal.NotifyContext(context.Background(), syscall.SIGINT) defer can() cfg, err := newConfig() if err != nil { panic(err) } if err := run(ctx, cfg); err != nil && ctx.Err() == nil { panic(err) } } func run(ctx context.Context, cfg Config) error { select { case <-ctx.Done(): return ctx.Err() case err := <-listenAndServe(ctx, cfg): return err } } func listenAndServe(ctx context.Context, cfg Config) chan error { s := http.Server{ Addr: fmt.Sprintf(":%d", cfg.Port), } errc := make(chan error) go func() { defer close(errc) errc <- s.ListenAndServe() }() return errc }