diff --git a/internal/database/database.go b/internal/database/database.go index b8d8040..409c1b0 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -91,19 +91,19 @@ func New(cfg *config.Config, logger *logger.Logger) (*Database, error) { func (d *Database) Initialize() error { // Set SQLite pragmas for better performance pragmas := []string{ - "PRAGMA journal_mode=WAL", // Write-Ahead Logging - "PRAGMA synchronous=OFF", // Don't wait for disk writes - "PRAGMA cache_size=-2097152", // 2GB cache (negative = KB) - "PRAGMA temp_store=MEMORY", // Use memory for temp tables - "PRAGMA mmap_size=536870912", // 512MB memory-mapped I/O - "PRAGMA wal_autocheckpoint=1000", // Checkpoint every 1000 pages (4MB with 4KB pages) - "PRAGMA wal_checkpoint(PASSIVE)", // Checkpoint now - "PRAGMA page_size=4096", // Standard page size - "PRAGMA busy_timeout=30000", // 30 second busy timeout - "PRAGMA locking_mode=NORMAL", // Allow multiple connections - "PRAGMA read_uncommitted=true", // Allow dirty reads for better concurrency - "PRAGMA journal_size_limit=67108864", // Limit WAL to 64MB - "PRAGMA analysis_limit=0", // Disable automatic ANALYZE + "PRAGMA journal_mode=WAL", // Write-Ahead Logging + "PRAGMA synchronous=OFF", // Don't wait for disk writes + "PRAGMA cache_size=-2097152", // 2GB cache (negative = KB) + "PRAGMA temp_store=MEMORY", // Use memory for temp tables + "PRAGMA mmap_size=536870912", // 512MB memory-mapped I/O + "PRAGMA wal_autocheckpoint=12500", // Checkpoint every 12.5k pages (50MB with 4KB pages) + "PRAGMA wal_checkpoint(PASSIVE)", // Checkpoint now + "PRAGMA page_size=4096", // Standard page size + "PRAGMA busy_timeout=2000", // 2 second busy timeout + "PRAGMA locking_mode=NORMAL", // Allow multiple connections + "PRAGMA read_uncommitted=true", // Allow dirty reads for better concurrency + "PRAGMA journal_size_limit=104857600", // Limit WAL to 100MB + "PRAGMA analysis_limit=0", // Disable automatic ANALYZE } for _, pragma := range pragmas { diff --git a/internal/routewatch/cli.go b/internal/routewatch/cli.go index 2c5d55a..92e707d 100644 --- a/internal/routewatch/cli.go +++ b/internal/routewatch/cli.go @@ -58,26 +58,25 @@ func CLIEntry() { app := fx.New( getModule(), fx.StopTimeout(shutdownTimeout), // Allow 60 seconds for graceful shutdown - fx.Invoke(func(lc fx.Lifecycle, rw *RouteWatch, logger *logger.Logger) { + fx.Invoke(func(lc fx.Lifecycle, rw *RouteWatch, logger *logger.Logger, shutdowner fx.Shutdowner) { lc.Append(fx.Hook{ - OnStart: func(_ context.Context) error { + OnStart: func(ctx context.Context) error { // Start debug stats logging go logDebugStats(logger) + // Handle shutdown signals + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + go func() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // Handle shutdown signals - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) - - go func() { - <-sigCh - logger.Info("Received shutdown signal") - cancel() - }() + <-sigCh + logger.Info("Received shutdown signal") + if err := shutdowner.Shutdown(); err != nil { + logger.Error("Failed to shutdown gracefully", "error", err) + } + }() + go func() { if err := rw.Run(ctx); err != nil { logger.Error("RouteWatch error", "error", err) }