From b7040cb8ca9df45347131c2efb832e8c90dd72f2 Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Fri, 28 Jun 2024 11:24:52 +1000 Subject: [PATCH] fix: startup commands would never run (#1905) Startup commands were being applied after the errgroup.Wait in `ftl dev`, which blocked forever. --- cmd/ftl/cmd_dev.go | 11 ++++++----- cmd/ftl/cmd_serve.go | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/cmd/ftl/cmd_dev.go b/cmd/ftl/cmd_dev.go index 84160f75bf..fbd6a4db89 100644 --- a/cmd/ftl/cmd_dev.go +++ b/cmd/ftl/cmd_dev.go @@ -8,6 +8,8 @@ import ( "golang.org/x/sync/errgroup" + "github.com/alecthomas/types/optional" + "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/ftlv1connect" "github.com/TBD54566975/ftl/buildengine" "github.com/TBD54566975/ftl/common/projectconfig" @@ -53,6 +55,8 @@ func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error return nil } + // cmdServe will notify this channel when startup commands are complete and the controller is ready + controllerReady := make(chan bool, 1) if !d.NoServe { if d.ServeCmd.Stop { err := d.ServeCmd.Run(ctx, projConfig) @@ -65,14 +69,11 @@ func (d *devCmd) Run(ctx context.Context, projConfig projectconfig.Config) error return errors.New(ftlRunningErrorMsg) } - g.Go(func() error { return d.ServeCmd.Run(ctx, projConfig) }) + g.Go(func() error { return d.ServeCmd.run(ctx, projConfig, optional.Some(controllerReady)) }) } g.Go(func() error { - err := waitForControllerOnline(ctx, d.ServeCmd.StartupTimeout, client) - if err != nil { - return err - } + <-controllerReady opts := []buildengine.Option{buildengine.Parallelism(d.Parallelism)} if d.Lsp { diff --git a/cmd/ftl/cmd_serve.go b/cmd/ftl/cmd_serve.go index 584d15d0e2..10a7a10442 100644 --- a/cmd/ftl/cmd_serve.go +++ b/cmd/ftl/cmd_serve.go @@ -15,6 +15,7 @@ import ( "connectrpc.com/connect" "github.com/alecthomas/kong" + "github.com/alecthomas/types/optional" "github.com/jackc/pgx/v5/pgxpool" "golang.org/x/sync/errgroup" @@ -48,6 +49,10 @@ const ftlContainerName = "ftl-db-1" const ftlRunningErrorMsg = "FTL is already running. Use 'ftl serve --stop' to stop it" func (s *serveCmd) Run(ctx context.Context, projConfig projectconfig.Config) error { + return s.run(ctx, projConfig, optional.None[chan bool]()) +} + +func (s *serveCmd) run(ctx context.Context, projConfig projectconfig.Config, initialised optional.Option[chan bool]) error { logger := log.FromContext(ctx) client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx) @@ -135,8 +140,9 @@ func (s *serveCmd) Run(ctx context.Context, projConfig projectconfig.Config) err }) } - if err := wg.Wait(); err != nil { - return fmt.Errorf("serve failed: %w", err) + // Wait for controller to start, then run startup commands. + if err := waitForControllerOnline(ctx, time.Second*10, client); err != nil { + return fmt.Errorf("controller failed to start: %w", err) } if len(projConfig.Commands.Startup) > 0 { @@ -148,6 +154,14 @@ func (s *serveCmd) Run(ctx context.Context, projConfig projectconfig.Config) err } } + if ch, ok := initialised.Get(); ok { + ch <- true + } + + if err := wg.Wait(); err != nil { + return fmt.Errorf("serve failed: %w", err) + } + return nil }