//go:generate oapi-codegen --config=oapi-codegen.yml openapi.yml package main import ( "code.dlmw.ch/dlmw/qv/internal/migrations" "code.dlmw.ch/dlmw/qv/internal/models" "context" "database/sql" "log/slog" _ "modernc.org/sqlite" "net/http" "os" "os/signal" "syscall" "time" ) var addr = ":8080" var databasePath string func init() { if os.Getenv("QV_DATABASE_PATH") == "" { databasePath = "./qv.sqlite" } else { databasePath = os.Getenv("QV_DATABASE_PATH") } } func main() { logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) db, err := openDb() if err != nil { logger.Error(err.Error()) os.Exit(1) } defer db.Close() err = migrations.Run(db) if err != nil { logger.Error(err.Error()) os.Exit(1) } app := &application{ logger: logger, elections: &models.ElectionModel{DB: db}, voters: &models.VoterModel{DB: db}, votes: &models.VoteModel{DB: db}, } logger.Info("Starting server", "addr", addr) srv := &http.Server{ Addr: addr, Handler: app.routes(), ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError), IdleTimeout: 30 * time.Second, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, } go watchForQuitSignals(srv, logger) if err = srv.ListenAndServe(); err != nil { logger.Error(err.Error()) os.Exit(1) } } func openDb() (*sql.DB, error) { db, err := sql.Open("sqlite", databasePath+"?_foreign_keys=on&_busy_timeout=5000") if err == nil { err = db.Ping() } return db, err } func watchForQuitSignals(srv *http.Server, logger *slog.Logger) { quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() s := <-quit logger.Info("caught signal", "signal", s.String()) srv.Shutdown(ctx) os.Exit(0) }