package main import ( "context" "fmt" "log" "net/http" "os" "os/signal" "syscall" "time" "osdb/internal/config" "osdb/internal/database" "osdb/internal/migrate" ) func main() { cfg := config.Load() args := os.Args[1:] switch { case len(args) >= 1 && args[0] == "migrate": if len(args) >= 2 && args[1] == "down" { if err := migrate.Down(cfg.DatabaseURL); err != nil { log.Fatalf("migrate down: %v", err) } log.Println("migrate down: done") } else { if err := migrate.Up(cfg.DatabaseURL); err != nil { log.Fatalf("migrate up: %v", err) } log.Println("migrate up: applied") } return default: serve(cfg) } } func serve(cfg *config.Config) { ctx := context.Background() pool, err := database.Connect(ctx, cfg.DatabaseURL) if err != nil { log.Fatalf("database connect: %v", err) } defer pool.Close() log.Println("database: connected") e := New(pool) // Start server go func() { addr := fmt.Sprintf(":%s", cfg.Port) log.Printf("server: listening on %s", addr) if err := e.Start(addr); err != nil && err != http.ErrServerClosed { log.Fatalf("server: %v", err) } }() // Graceful shutdown on SIGINT / SIGTERM quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("server: shutting down") shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := e.Shutdown(shutdownCtx); err != nil { log.Printf("server: shutdown error: %v", err) } }