package main import ( "context" "fmt" "log" "net/http" "os/signal" "syscall" "time" "golang.org/x/time/rate" ) func main() { ctx, can := signal.NotifyContext(context.Background(), syscall.SIGINT) defer can() if err := run(ctx); err != nil { panic(err) } } func run(ctx context.Context) error { config, err := NewConfig(ctx) if err != nil { return err } db, err := NewDB(ctx, config.DB.Scheme, config.DB.Conn) if err != nil { return err } games, err := NewGames(ctx, db) if err != nil { return err } S := &S{ ctx: ctx, limiter: rate.NewLimiter(10, 10), config: config, games: games, } s := &http.Server{ Addr: fmt.Sprintf(":%d", config.Port), Handler: S, } go func() { <-ctx.Done() ctx, can := context.WithTimeout(context.Background(), time.Second) defer can() s.Shutdown(ctx) }() log.Println("listening on", config.Port) if err := s.ListenAndServe(); err != nil && ctx.Err() == nil { return err } log.Println("shut down") return nil }