Skip to content

Commit

Permalink
fix: parallelize deployments (#1042)
Browse files Browse the repository at this point in the history
Fixes #1031

Introduces non-blocking deploys so that they can while other modules are
build.

BEFORE (20s cold, 11s warm):
![Screenshot 2024-03-07 at 1 28
09 PM](https://github.com/TBD54566975/ftl/assets/51647/f03b0cfe-8c77-4aba-aee7-689561391618)

AFTER (16s cold, 8s warm):
![Screenshot 2024-03-07 at 1 29
23 PM](https://github.com/TBD54566975/ftl/assets/51647/8148625e-7b5d-4082-84fe-4a7fffca60e4)
  • Loading branch information
wesbillman authored Mar 7, 2024
1 parent e8b0a36 commit 2bfa633
Showing 1 changed file with 39 additions and 9 deletions.
48 changes: 39 additions & 9 deletions buildengine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,7 @@ func (e *Engine) Dev(ctx context.Context, period time.Duration) error {
logger := log.FromContext(ctx)

// Build and deploy all modules first.
err := e.buildWithCallback(ctx, func(ctx context.Context, module Module) error {
return Deploy(ctx, module, 1, true, e.client)
})
err := e.buildAndDeploy(ctx, 1, true)
if err != nil {
logger.Errorf(err, "initial deploy failed")
}
Expand Down Expand Up @@ -223,13 +221,45 @@ func (e *Engine) Dev(ctx context.Context, period time.Duration) error {
}

func (e *Engine) buildAndDeploy(ctx context.Context, replicas int32, waitForDeployOnline bool, modules ...string) error {
err := e.buildWithCallback(ctx, func(ctx context.Context, module Module) error {
return Deploy(ctx, module, replicas, waitForDeployOnline, e.client)
}, modules...)
if err != nil {
return err
if len(modules) == 0 {
modules = maps.Keys(e.modules)
}
return nil

deployQueue := make(chan Module, len(modules))
wg, ctx := errgroup.WithContext(ctx)

wg.Go(func() error {
defer close(deployQueue)

return e.buildWithCallback(ctx, func(ctx context.Context, module Module) error {
select {
case deployQueue <- module:
return nil
case <-ctx.Done():
return ctx.Err()
}
}, modules...)
})

for i := 0; i < len(modules); i++ {
wg.Go(func() error {
for {
select {
case module, ok := <-deployQueue:
if !ok {
return nil
}
if err := Deploy(ctx, module, replicas, waitForDeployOnline, e.client); err != nil {
return err
}
case <-ctx.Done():
return ctx.Err()
}
}
})
}

return wg.Wait()
}

type buildCallback func(ctx context.Context, module Module) error
Expand Down

0 comments on commit 2bfa633

Please sign in to comment.