package main import ( "context" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "stow/backend/internal/api" "stow/backend/internal/store" ) func main() { logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) databaseURL := os.Getenv("DATABASE_URL") if databaseURL == "" { logger.Error("DATABASE_URL is required") os.Exit(1) } ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() dataStore, err := store.Open(ctx, databaseURL) if err != nil { logger.Error("database unavailable", "error", err) os.Exit(1) } defer dataStore.Close() port := os.Getenv("PORT") if port == "" { port = "8080" } server := &http.Server{Addr: ":" + port, Handler: api.New(dataStore), ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 15 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second} go func() { <-ctx.Done() shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() _ = server.Shutdown(shutdownCtx) }() logger.Info("stow api listening", "port", port) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Error("server stopped", "error", err) os.Exit(1) } }