Multiple implementations of the same back-end application. The aim is to provide quick, side-by-side comparisons of different technologies (languages, frameworks, libraries) while preserving consistent business logic across all implementations.
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

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)
}