diff --git a/cmd/server/main.go b/cmd/server/main.go new file mode 100644 index 0000000..055e4af --- /dev/null +++ b/cmd/server/main.go @@ -0,0 +1,73 @@ +package main + +import ( + "context" + "log/slog" + "os" + "os/signal" + "syscall" + "time" + + "hash-of-wisdom/internal/lib/sl" + "hash-of-wisdom/internal/pow/challenge" + "hash-of-wisdom/internal/quotes" + "hash-of-wisdom/internal/server" + "hash-of-wisdom/internal/service" +) + +func main() { + addr := ":8080" + if len(os.Args) > 1 { + addr = os.Args[1] + } + + logger := slog.Default() + logger.Info("starting word of wisdom server", "address", addr) + + // Create components + challengeConfig, err := challenge.NewConfig() + if err != nil { + logger.Error("failed to create config", sl.Err(err)) + os.Exit(1) + } + generator := challenge.NewGenerator(challengeConfig) + verifier := challenge.NewVerifier(challengeConfig) + quoteService := quotes.NewHTTPService() + + // Wire up service + genAdapter := service.NewGeneratorAdapter(generator) + wisdomService := service.NewWisdomService(genAdapter, verifier, quoteService) + + // Create server configuration + serverConfig := server.DefaultConfig() + serverConfig.Address = addr + + // Create server + srv := server.NewTCPServer(wisdomService, + server.WithConfig(serverConfig), + server.WithLogger(logger)) + + // Start server + ctx := context.Background() + if err := srv.Start(ctx); err != nil { + logger.Error("failed to start server", sl.Err(err)) + os.Exit(1) + } + + // Wait for interrupt + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + + logger.Info("server ready - press ctrl+c to stop") + <-sigChan + + // Graceful shutdown + logger.Info("shutting down server") + if err := srv.Stop(); err != nil { + logger.Error("error during shutdown", sl.Err(err)) + } + + // Give connections time to close + time.Sleep(100 * time.Millisecond) + logger.Info("server stopped") +}