Skip to content

Commit

Permalink
feat: run ftl serve as part of ftl dev (#987)
Browse files Browse the repository at this point in the history
Fixes #979 

New help exposes embedded `serve-` flags:
```sh
ftl dev --help

Usage: ftl dev [<base-dir>]

Watch a directory for FTL modules and hot reload them.

Arguments:
  [<base-dir>]    Directory to watch for FTL modules

Flags:
  -h, --help           Show context-sensitive help.
      --version        Show version.
      --config=FILE    Load configuration from TOML file.
      --endpoint=http://127.0.0.1:8892
                       FTL endpoint to bind/connect to ($FTL_ENDPOINT).
      --authenticators=HOST=EXE,…
                       Authenticators to use for FTL endpoints ($FTL_AUTHENTICATORS).

Logging:
  --log-level=info    Log level ($LOG_LEVEL).
  --log-json          Log in JSON format ($LOG_JSON).

Command flags:
      --watch=500ms            Watch template directory at this frequency and regenerate
                               on change.
      --failure-delay=500ms    Delay before retrying a failed deploy.
      --reconnect-delay=1s     Delay before attempting to reconnect to FTL.
      --exit-after-deploy      Exit after all modules are deployed successfully.
      --no-serve               Do not start the FTL server.
      --serve-bind=http://localhost:8892
                               Starting endpoint to bind to and advertise to. Each
                               controller and runner will increment the port by 1
      --serve-allow-origins=SERVE-ALLOW-ORIGINS,...
                               Allow CORS requests to ingress endpoints from these origins
                               ($FTL_CONTROLLER_ALLOW_ORIGIN).
      --serve-db-port=54320    Port to use for the database.
      --serve-recreate         Recreate the database even if it already exists.
  -c, --serve-controllers=1    Number of controllers to start.
  -r, --serve-runners=0        Number of runners to start.
      --serve-background       Run in the background.
      --serve-stop             Stop the running FTL instance.
```

`ftl dev` with server and flags
```sh
ftl dev examples/go --serve-recreate

info: Starting FTL with 1 controller(s) and 0 runner(s)
warn: Detected change in +/Users/wesbillman/dev/ftl/examples/go/echo/echo.go, rebuilding...
error: Error deploying module /Users/wesbillman/dev/ftl/examples/go/echo. Will retry: module "time" not found
warn: Detected change in +/Users/wesbillman/dev/ftl/examples/go/time/time.go, rebuilding...
info:time: Building module
info:controller0: Web console available at: http://localhost:5173
info: Preparing module 'time' for deployment
info: Successfully created deployment time-e0368491b5
info:echo: Building module
info: Preparing module 'echo' for deployment
info: Successfully created deployment echo-092543e753
```

`ftl dev` without server
```sh
ftl dev examples/go --no-serve

warn: Detected change in +/Users/wesbillman/dev/ftl/examples/go/echo/go.sum, rebuilding...
error: Error deploying module /Users/wesbillman/dev/ftl/examples/go/echo. Will retry: module "time" not found
warn: Detected change in +/Users/wesbillman/dev/ftl/examples/go/time/go.mod, rebuilding...
info:time: Building module
info: Preparing module 'time' for deployment
error: Error deploying module /Users/wesbillman/dev/ftl/examples/go/time. Will retry: unavailable: dial tcp [::1]:8892: connect: connection refused
info:time: Building module
info: Preparing module 'time' for deployment
error: Error deploying module /Users/wesbillman/dev/ftl/examples/go/time. Will retry: unavailable: dial tcp [::1]:8892: connect: connection refused
error: Error deploying module /Users/wesbillman/dev/ftl/examples/go/echo. Will retry: module "time" not found
```
  • Loading branch information
wesbillman authored Feb 26, 2024
1 parent 4155488 commit 4d176d4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
20 changes: 16 additions & 4 deletions cmd/ftl/cmd_dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/TBD54566975/ftl/buildengine"
"github.com/TBD54566975/ftl/common/moduleconfig"
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/internal/rpc"
)

type moduleFolderInfo struct {
Expand All @@ -30,6 +31,8 @@ type devCmd struct {
FailureDelay time.Duration `help:"Delay before retrying a failed deploy." default:"500ms"`
ReconnectDelay time.Duration `help:"Delay before attempting to reconnect to FTL." default:"1s"`
ExitAfterDeploy bool `help:"Exit after all modules are deployed successfully." default:"false"`
NoServe bool `help:"Do not start the FTL server." default:"false"`
ServeCmd serveCmd `embed:"" prefix:"serve-"`
}

type moduleMap map[string]*moduleFolderInfo
Expand Down Expand Up @@ -88,17 +91,26 @@ func (m *moduleMap) RebuildDependentModules(ctx context.Context, sch *schema.Mod
}
}

func (d *devCmd) Run(ctx context.Context, client ftlv1connect.ControllerServiceClient) error {
func (d *devCmd) Run(ctx context.Context) error {
logger := log.FromContext(ctx)
logger.Debugf("Watching %s for FTL modules", d.BaseDir)
client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx)

ctx, cancel := context.WithCancel(ctx)
defer cancel()

wg, ctx := errgroup.WithContext(ctx)

if !d.NoServe {
wg.Go(func() error {
return d.ServeCmd.Run(ctx)
})
}

logger.Debugf("Watching %s for FTL modules", d.BaseDir)

schemaChanges := make(chan *schema.Module, 64)
modules := make(moduleMap)

wg, ctx := errgroup.WithContext(ctx)

wg.Go(func() error {
return d.watchForSchemaChanges(ctx, client, schemaChanges)
})
Expand Down
4 changes: 3 additions & 1 deletion cmd/ftl/cmd_serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/TBD54566975/ftl/internal/bind"
"github.com/TBD54566975/ftl/internal/exec"
"github.com/TBD54566975/ftl/internal/log"
"github.com/TBD54566975/ftl/internal/rpc"
"github.com/TBD54566975/ftl/internal/slices"
)

Expand All @@ -41,8 +42,9 @@ type serveCmd struct {

const ftlContainerName = "ftl-db-1"

func (s *serveCmd) Run(ctx context.Context, client ftlv1connect.ControllerServiceClient) error {
func (s *serveCmd) Run(ctx context.Context) error {
logger := log.FromContext(ctx)
client := rpc.ClientFromContext[ftlv1connect.ControllerServiceClient](ctx)

if s.Background {
runInBackground(logger)
Expand Down

0 comments on commit 4d176d4

Please sign in to comment.