You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.5 KiB
94 lines
2.5 KiB
package main |
|
|
|
import ( |
|
"context" |
|
"log" |
|
"net/http" |
|
"os" |
|
"os/signal" |
|
"syscall" |
|
"time" |
|
|
|
"autostore/internal/application/interfaces" |
|
"autostore/internal/config" |
|
"autostore/internal/container" |
|
) |
|
|
|
func main() { |
|
// Load configuration |
|
cfg, err := config.Load() |
|
if err != nil { |
|
log.Fatalf("Failed to load configuration: %v", err) |
|
} |
|
|
|
// Validate configuration |
|
if err := cfg.Validate(); err != nil { |
|
log.Fatalf("Invalid configuration: %v", err) |
|
} |
|
|
|
// Create dependency injection container |
|
container := container.NewContainer(cfg) |
|
if err := container.Initialize(); err != nil { |
|
log.Fatalf("Failed to initialize container: %v", err) |
|
} |
|
|
|
// Get server and scheduler from container |
|
server := container.GetServer() |
|
scheduler := container.GetExpiredItemsScheduler() |
|
logger := container.GetLogger() |
|
|
|
// Setup graceful shutdown |
|
shutdownComplete := make(chan struct{}) |
|
go setupGracefulShutdown(server, scheduler, logger, shutdownComplete) |
|
|
|
// Start scheduler |
|
if err := scheduler.Start(context.Background()); err != nil { |
|
logger.Error(context.Background(), "Failed to start scheduler", "error", err) |
|
log.Fatalf("Failed to start scheduler: %v", err) |
|
} |
|
|
|
// Start server |
|
if err := server.Start(); err != nil { |
|
if err == http.ErrServerClosed { |
|
// This is expected during graceful shutdown |
|
logger.Info(context.Background(), "Server shutdown complete") |
|
} else { |
|
logger.Error(context.Background(), "Server failed to start", "error", err) |
|
log.Fatalf("Server failed to start: %v", err) |
|
} |
|
} |
|
|
|
// Wait for graceful shutdown to complete |
|
<-shutdownComplete |
|
logger.Info(context.Background(), "Application exiting gracefully") |
|
} |
|
|
|
func setupGracefulShutdown(server interface { |
|
Shutdown(ctx context.Context) error |
|
}, scheduler interface { |
|
Stop() error |
|
}, logger interfaces.ILogger, shutdownComplete chan struct{}) { |
|
sigChan := make(chan os.Signal, 1) |
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) |
|
|
|
sig := <-sigChan |
|
logger.Info(context.Background(), "Received shutdown signal", "signal", sig) |
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) |
|
defer cancel() |
|
|
|
if err := scheduler.Stop(); err != nil { |
|
logger.Error(ctx, "Scheduler shutdown failed", "error", err) |
|
} else { |
|
logger.Info(ctx, "Scheduler shutdown completed gracefully") |
|
} |
|
|
|
if err := server.Shutdown(ctx); err != nil { |
|
logger.Error(ctx, "Server shutdown failed", "error", err) |
|
} else { |
|
logger.Info(ctx, "Server shutdown completed gracefully") |
|
} |
|
|
|
// Signal that shutdown is complete |
|
close(shutdownComplete) |
|
}
|
|
|