diff options
Diffstat (limited to 'internal/cli/serve.go')
| -rw-r--r-- | internal/cli/serve.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/internal/cli/serve.go b/internal/cli/serve.go new file mode 100644 index 0000000..5d41395 --- /dev/null +++ b/internal/cli/serve.go @@ -0,0 +1,86 @@ +package cli + +import ( + "context" + "fmt" + "log/slog" + "net/http" + "os" + "os/signal" + "syscall" + "time" + + "github.com/claudomator/claudomator/internal/api" + "github.com/claudomator/claudomator/internal/executor" + "github.com/claudomator/claudomator/internal/storage" + "github.com/spf13/cobra" +) + +func newServeCmd() *cobra.Command { + var addr string + + cmd := &cobra.Command{ + Use: "serve", + Short: "Start the Claudomator API server", + RunE: func(cmd *cobra.Command, args []string) error { + return serve(addr) + }, + } + + cmd.Flags().StringVar(&addr, "addr", ":8484", "listen address") + + return cmd +} + +func serve(addr string) error { + if err := cfg.EnsureDirs(); err != nil { + return fmt.Errorf("creating dirs: %w", err) + } + + store, err := storage.Open(cfg.DBPath) + if err != nil { + return fmt.Errorf("opening db: %w", err) + } + defer store.Close() + + level := slog.LevelInfo + if verbose { + level = slog.LevelDebug + } + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level})) + + runner := &executor.ClaudeRunner{ + BinaryPath: cfg.ClaudeBinaryPath, + Logger: logger, + LogDir: cfg.LogDir, + } + pool := executor.NewPool(cfg.MaxConcurrent, runner, store, logger) + + srv := api.NewServer(store, pool, logger) + srv.StartHub() + + httpSrv := &http.Server{ + Addr: addr, + Handler: srv.Handler(), + } + + // Graceful shutdown. + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM) + go func() { + <-sigCh + logger.Info("shutting down server...") + shutdownCtx, shutdownCancel := context.WithTimeout(ctx, 5*time.Second) + defer shutdownCancel() + httpSrv.Shutdown(shutdownCtx) + }() + + fmt.Printf("Claudomator server listening on %s\n", addr) + if err := httpSrv.ListenAndServe(); err != http.ErrServerClosed { + return err + } + return nil +} |
