diff --git a/frontend/cli/cmd_dev.go b/frontend/cli/cmd_dev.go index 455ac99169..829e4b8957 100644 --- a/frontend/cli/cmd_dev.go +++ b/frontend/cli/cmd_dev.go @@ -50,6 +50,9 @@ func (d *devCmd) Run( verbClient ftlv1connect.VerbServiceClient, ) error { startTime := time.Now() + logger := log.FromContext(ctx) + ctx, cancel := context.WithCancel(ctx) + defer cancel() if len(d.Build.Dirs) == 0 { d.Build.Dirs = projConfig.AbsModuleDirs() } @@ -78,6 +81,7 @@ func (d *devCmd) Run( return nil } statusManager := terminal.FromContext(ctx) + defer statusManager.Close() starting := statusManager.NewStatus("\u001B[92mStarting FTL Server 🚀\u001B[39m") bindAllocator, err := bind.NewBindAllocator(d.ServeCmd.Bind, 1) @@ -102,7 +106,9 @@ func (d *devCmd) Run( } g.Go(func() error { - return d.ServeCmd.run(ctx, projConfig, cm, sm, optional.Some(controllerReady), true, bindAllocator, controllerClient, provisionerClient, schemaEventSourceFactory, verbClient, true, devModeEndpointUpdates) + err := d.ServeCmd.run(ctx, projConfig, cm, sm, optional.Some(controllerReady), true, bindAllocator, controllerClient, provisionerClient, schemaEventSourceFactory, verbClient, true, devModeEndpointUpdates) + cancel() + return err }) } @@ -133,5 +139,10 @@ func (d *devCmd) Run( return engine.Dev(ctx, d.Watch) }) - return g.Wait() + err = g.Wait() + if err != nil { + logger.Errorf(err, "error during dev") + return fmt.Errorf("error during dev: %w", err) + } + return nil } diff --git a/frontend/cli/cmd_serve.go b/frontend/cli/cmd_serve.go index b63cd6af2c..c2c6d7b8a8 100644 --- a/frontend/cli/cmd_serve.go +++ b/frontend/cli/cmd_serve.go @@ -116,7 +116,11 @@ func (s *serveCommonConfig) run( // allow usage of --background and --stop together to "restart" the background process _ = KillBackgroundServe(logger) //nolint:errcheck // ignore error here if the process is not running } - + _, err := controllerClient.Ping(ctx, connect.NewRequest(&ftlv1.PingRequest{})) + if err == nil { + // The controller is already running, bail out. + return fmt.Errorf("controller is already running") + } if err := runInBackground(logger); err != nil { return err } @@ -136,7 +140,11 @@ func (s *serveCommonConfig) run( if s.Stop { return KillBackgroundServe(logger) } - + _, err := controllerClient.Ping(ctx, connect.NewRequest(&ftlv1.PingRequest{})) + if err == nil { + // The controller is already running, bail out. + return fmt.Errorf("controller is already running") + } if s.Provisioners > 0 { logger.Debugf("Starting FTL with %d controller(s) and %d provisioner(s)", s.Controllers, s.Provisioners) } else { @@ -154,7 +162,7 @@ func (s *serveCommonConfig) run( s.ObservabilityConfig.ExportOTEL = true } } - err := observability.Init(ctx, false, "", "ftl-serve", ftl.Version, s.ObservabilityConfig) + err = observability.Init(ctx, false, "", "ftl-serve", ftl.Version, s.ObservabilityConfig) if err != nil { return fmt.Errorf("observability init failed: %w", err) }