package cmd import ( "context" "errors" "log/slog" nethttp "net/http" "os" "os/signal" "syscall" "time" "github.com/spf13/cobra" "trankilou.fr/lassistanoque/backend/internal/brain" "trankilou.fr/lassistanoque/backend/internal/http" "trankilou.fr/lassistanoque/backend/internal/service/agent" "trankilou.fr/lassistanoque/backend/internal/service/auth" "trankilou.fr/lassistanoque/backend/internal/service/chat" "trankilou.fr/lassistanoque/backend/internal/service/provider" "trankilou.fr/lassistanoque/backend/internal/service/storage" "trankilou.fr/lassistanoque/backend/internal/service/user" ) func init() { rootCmd.AddCommand( newServeCmd(), ) } func newServeCmd() *cobra.Command { var short bool cmd := &cobra.Command{ Use: "serve", Short: "Run server", Run: func(cmd *cobra.Command, args []string) { runServe() }, } cmd.Flags().BoolVarP(&short, "short", "s", false, "show only version number") return cmd } func runServe() { defer Close() // services authService := auth.NewService(GetSettingsRepository(), GetUserRepository(), GetAuthenticators()) userService := user.NewService(GetUserRepository()) storageService := storage.NewService(GetStorageProvider()) providerService := provider.NewService(GetProviderRepository(), GetUserRepository(), GetLLMEngine()) agentService := agent.NewService(GetAgentRepository(), GetUserRepository()) chatService := chat.NewService(GetUserRepository(), GetAgentRepository(), GetProviderRepository(), GetChatRepository(), GetLLMEngine()) // http server httpRouter := http.NewRouter(http.Dependencies{ StorageService: storageService, AuthService: authService, UserService: userService, ProviderService: providerService, AgentService: agentService, ChatService: chatService, TokenManager: GetTokenManager(), }) brainRouter := brain.NewRouter(brain.Dependencies{ ChatRepository: GetChatRepository(), }) ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) defer stop() // start Brain router go func() { if err := brainRouter.Start(); err != nil && !errors.Is(err, nethttp.ErrServerClosed) { slog.Error("failed to start llm server", "error", err) } }() // start HTTP router go func() { if err := httpRouter.Start(); err != nil && !errors.Is(err, nethttp.ErrServerClosed) { slog.Error("failed to start http server", "error", err) } }() <-ctx.Done() // stop HTTP service ctx, cancel1 := context.WithTimeout(context.Background(), 10*time.Second) defer cancel1() if err := httpRouter.Stop(ctx); err != nil { slog.Error("failed to stop http server", "error", err) } slog.Info("HTTP server stopped gracefully") // stop LLM service ctx, cancel2 := context.WithTimeout(context.Background(), 10*time.Second) defer cancel2() if err := brainRouter.Stop(ctx); err != nil { slog.Error("failed to stop llm server", "error", err) } slog.Info("LLM server stopped gracefully") }