box/internal/app/run.go
2026-05-15 17:40:09 +02:00

67 lines
1.5 KiB
Go

package app
import (
"context"
"database/sql"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/joho/godotenv"
)
func initApp() (*App, func(), error) {
_ = godotenv.Load()
cfg, err := loadConfig()
if err != nil {
return nil, nil, fmt.Errorf("config error: %w", err)
}
db, err := sql.Open("pgx", cfg.DatabaseURL)
if err != nil {
return nil, nil, fmt.Errorf("database open error: %w", err)
}
cleanup := func() { _ = db.Close() }
if err := db.Ping(); err != nil {
cleanup()
return nil, nil, fmt.Errorf("database ping error: %w", err)
}
a := &App{cfg: cfg, db: db}
if err := a.migrate(context.Background()); err != nil {
cleanup()
return nil, nil, fmt.Errorf("migration error: %w", err)
}
return a, cleanup, nil
}
func Run() error {
app, cleanup, err := initApp()
if err != nil {
return err
}
defer cleanup()
handler := app.routes()
servers, sockCleanup, err := startServers(app.cfg, handler)
if err != nil {
return fmt.Errorf("server start error: %w", err)
}
defer sockCleanup()
log.Printf("server started: tcp=%q unix=%q dev_mode=%t", app.cfg.ListenAddr, app.cfg.UnixSocketPath, app.cfg.DevMode)
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
<-sigCh
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
for _, s := range servers {
if err := s.Shutdown(ctx); err != nil {
log.Printf("shutdown error: %v", err)
}
}
log.Printf("shutdown complete")
return nil
}