Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use buildengine for deploy cmd #1002

Merged
merged 5 commits into from
Mar 5, 2024
Merged

feat: use buildengine for deploy cmd #1002

merged 5 commits into from
Mar 5, 2024

Conversation

wesbillman
Copy link
Collaborator

@wesbillman wesbillman commented Feb 28, 2024

Not fully tested yet, but starting to flesh out the subscription flow for build -> deploy

ftl deploy ../ftl-examples/online-boutique/backend/services examples/go

info:time: Building module
info:ad: Building module
info:currency: Building module
info:cart: Building module
info:cart: Deploying module
info:ad: Deploying module
info:time: Deploying module
info:currency: Deploying module
info:shipping: Building module
info:productcatalog: Building module
info:payment: Building module
info:echo: Building module
info:shipping: Deploying module
info:payment: Deploying module
info:echo: Deploying module
info:productcatalog: Deploying module
info:recommendation: Building module
info:checkout: Building module
info:recommendation: Deploying module
info:checkout: Deploying module

ctx = log.ContextWithLogger(ctx, logger)
logger.Infof("Deploying module")

deployDir := filepath.Join(module.Dir, module.DeployDir)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated but I keep having to do this, maybe we should add helper methods that do the joining for us, eg. module.AbsDeployDir()

Or maybe we should make DeployDir et al absolute when we load the config. Not sure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah same! I'll add the module.AbsDeployDir for now and maybe we can clean this up with the DeployDir stuff if that makes sense

@@ -201,6 +206,56 @@ func (e *Engine) Build(ctx context.Context, modules ...string) error {
return nil
}

func (e *Engine) Deploy(ctx context.Context, replicas int32, waitForDeployOnline bool, modules ...string) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a comment.

modules = maps.Keys(e.modules)
}

buildSubscription := e.builds.SubscribeSync(nil)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't bother with pubsub for an internal implementation. It's useful for decoupling components, but if all your code is in a single type then it's just overhead. I'd probably refactor the exist build code into a function that can accept a callback that is executed after each module is built.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I like that! I'll give it a go

}

_, err = client.ReplaceDeploy(ctx, connect.NewRequest(&ftlv1.ReplaceDeployRequest{DeploymentName: resp.Msg.GetDeploymentName(), MinReplicas: d.Replicas}))
func (d *deployCmd) Run(ctx context.Context) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW both these approaches work - clients in context and clients passed directly.

localPath string
}

func Deploy(ctx context.Context, module Module, replicas int32, waitForDeployOnline bool, client ftlv1connect.ControllerServiceClient) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a comment.

// Build attempts to build the specified modules, or all local modules if none are provided.
func (e *Engine) Build(ctx context.Context, modules ...string) error {
// The callback is invoked for each module after it is built.
func (e *Engine) Build(ctx context.Context, callback BuildCallback, modules ...string) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback is (currently) an internal implementation detail only used by Deploy, just make its use private.

@wesbillman wesbillman force-pushed the create-engine-deploy branch from 24c37ef to 4df9870 Compare March 1, 2024 17:38
@wesbillman wesbillman marked this pull request as ready for review March 1, 2024 17:49
@wesbillman wesbillman force-pushed the create-engine-deploy branch from 7806df1 to 00a755e Compare March 1, 2024 17:49
}

// Deploy attempts to build and deploy the specified modules, or all local modules if none are provided.
func (e *Engine) Deploy(ctx context.Context, replicas int32, waitForDeployOnline bool, modules ...string) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a better idea really, but passing the same number of replicas for all deployments probably isn't what we'll want longer term.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah same. I wasn't 100% sure what to do here either, but open to improvements. Maybe we give this a go and if we have some use cases in the future that need something else we can update.

}

return e.buildWithCallback(ctx, func(ctx context.Context, module Module) error {
return Deploy(ctx, module, replicas, waitForDeployOnline, e.client)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having this wait for each deploy in turn will significantly slow down the deploy, as the build won't be able to continue until each group has fully deployed.

OTOH this will mean the deployed services will always have the correct dependencies up, so I'm a bit conflicted.

Probably okay for now, but we'll see how it goes. I think what would ideally happen is that deployments that don't have all the correct dependencies available wouldn't go live.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Word! I was thinking, this is nice and reliable for now, but probably can be quicker in the future. I had it deploying without a wait, but def ran into issues with complex dependencies. Maybe something we can chat through to see if we can make this fast and reliable.

@wesbillman wesbillman force-pushed the create-engine-deploy branch from 4a9a9c1 to 574087a Compare March 5, 2024 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants