mirror of
https://github.com/Dvorinka/SEEN.git
synced 2026-06-04 20:43:03 +00:00
116 lines
3.4 KiB
Go
116 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/tdvorak/seen/backend/internal/api"
|
|
"github.com/tdvorak/seen/backend/internal/api/handlers"
|
|
"github.com/tdvorak/seen/backend/internal/config"
|
|
"github.com/tdvorak/seen/backend/internal/downloader"
|
|
"github.com/tdvorak/seen/backend/internal/integrations/cache"
|
|
"github.com/tdvorak/seen/backend/internal/integrations/igdb"
|
|
"github.com/tdvorak/seen/backend/internal/repositories/postgres"
|
|
"github.com/tdvorak/seen/backend/internal/scanner"
|
|
"github.com/tdvorak/seen/backend/internal/services/auth"
|
|
"github.com/tdvorak/seen/backend/internal/services/catalog"
|
|
"github.com/tdvorak/seen/backend/internal/services/download"
|
|
"github.com/tdvorak/seen/backend/internal/workers"
|
|
"github.com/tdvorak/seen/backend/pkg/logger"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func main() {
|
|
cfg := config.Load()
|
|
log := logger.New(cfg.Env)
|
|
defer func() {
|
|
_ = log.Sync()
|
|
}()
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
|
defer stop()
|
|
|
|
pgPool, err := postgres.NewPool(ctx, cfg.Postgres, log)
|
|
if err != nil {
|
|
log.Fatal("postgres startup failed", zap.Error(err))
|
|
}
|
|
defer pgPool.Close()
|
|
|
|
cacheManager, err := cache.NewManager(ctx, cfg.Cache, log)
|
|
if err != nil {
|
|
log.Fatal("dragonfly startup failed", zap.Error(err))
|
|
}
|
|
defer func() {
|
|
if err := cacheManager.Close(); err != nil {
|
|
log.Error("failed to close cache manager", zap.Error(err))
|
|
}
|
|
}()
|
|
|
|
// Warmup cache with common data
|
|
if err := cacheManager.WarmupCache(ctx); err != nil {
|
|
log.Warn("cache warmup failed", zap.Error(err))
|
|
}
|
|
|
|
authRepository := postgres.NewAuthRepository(pgPool)
|
|
catalogRepository := postgres.NewCatalogRepository(pgPool)
|
|
downloadRepository := postgres.NewDownloadRepository(pgPool)
|
|
|
|
authService := auth.NewService(authRepository, cfg.Auth, log)
|
|
catalogService := catalog.NewService(catalogRepository)
|
|
downloadService := download.NewService(downloadRepository)
|
|
igdbClient := igdb.NewClient(cfg.IGDB)
|
|
if igdbClient.Enabled() {
|
|
catalogService.SetGameLookup(igdbClient)
|
|
log.Info("igdb live search enabled")
|
|
}
|
|
|
|
healthHandler := handlers.NewHealthHandler(pgPool, cacheManager.Client())
|
|
authHandler := handlers.NewAuthHandler(authService)
|
|
catalogHandler := handlers.NewCatalogHandler(catalogService, authService)
|
|
downloadHandler := handlers.NewDownloadHandler(downloadService, authService)
|
|
placeholderHandler := handlers.NewPlaceholderHandler()
|
|
|
|
router := api.NewRouter(cfg, log, api.Handlers{
|
|
Health: healthHandler,
|
|
Auth: authHandler,
|
|
Catalog: catalogHandler,
|
|
Download: downloadHandler,
|
|
Placeholder: placeholderHandler,
|
|
})
|
|
|
|
workerManager := workers.NewManager(
|
|
log,
|
|
downloader.NewWorker(log),
|
|
scanner.NewWorker(log),
|
|
)
|
|
workerManager.Start(ctx)
|
|
|
|
httpServer := &http.Server{
|
|
Addr: cfg.HTTP.Addr(),
|
|
Handler: router,
|
|
ReadTimeout: cfg.HTTP.ReadTimeout,
|
|
WriteTimeout: cfg.HTTP.WriteTimeout,
|
|
}
|
|
|
|
go func() {
|
|
log.Info("http server started", zap.String("addr", cfg.HTTP.Addr()))
|
|
if err := httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
|
log.Fatal("http server failed", zap.Error(err))
|
|
}
|
|
}()
|
|
|
|
<-ctx.Done()
|
|
log.Info("shutdown signal received")
|
|
|
|
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
defer cancel()
|
|
|
|
if err := httpServer.Shutdown(shutdownCtx); err != nil {
|
|
log.Error("graceful shutdown failed", zap.Error(err))
|
|
}
|
|
}
|