Skip to content

Commit

Permalink
fixing container log, parallel execution, code dupe and process stuck
Browse files Browse the repository at this point in the history
  • Loading branch information
zulkhair committed Sep 11, 2024
1 parent 096d3c4 commit ca1e9dd
Show file tree
Hide file tree
Showing 17 changed files with 794 additions and 240 deletions.
1 change: 0 additions & 1 deletion cmd/world/cardinal/cardinal.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ var BaseCmd = &cobra.Command{
dependency.Go,
dependency.Git,
dependency.Docker,
dependency.DockerCompose,
dependency.DockerDaemon,
)
},
Expand Down
39 changes: 25 additions & 14 deletions cmd/world/cardinal/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,20 +132,26 @@ func startCardinalDevMode(ctx context.Context, cfg *config.Config, prettyLog boo
// Check and wait until Redis is running and is available in the expected port
isRedisHealthy := false
for !isRedisHealthy {
redisAddress := fmt.Sprintf("localhost:%s", RedisPort)
conn, err := net.DialTimeout("tcp", redisAddress, time.Second)
if err != nil {
logger.Printf("Failed to connect to Redis at %s: %s\n", redisAddress, err)
time.Sleep(1 * time.Second)
continue
}
// using select to allow for context cancellation
select {
case <-ctx.Done():
return eris.Wrap(ctx.Err(), "Context canceled")

Check warning on line 138 in cmd/world/cardinal/dev.go

View check run for this annotation

Codecov / codecov/patch

cmd/world/cardinal/dev.go#L137-L138

Added lines #L137 - L138 were not covered by tests
default:
redisAddress := fmt.Sprintf("localhost:%s", RedisPort)
conn, err := net.DialTimeout("tcp", redisAddress, time.Second)
if err != nil {
logger.Printf("Failed to connect to Redis at %s: %s\n", redisAddress, err)
time.Sleep(1 * time.Second)
continue
}

// Cleanup connection
if err := conn.Close(); err != nil {
continue
}
// Cleanup connection
if err := conn.Close(); err != nil {
continue

Check warning on line 150 in cmd/world/cardinal/dev.go

View check run for this annotation

Codecov / codecov/patch

cmd/world/cardinal/dev.go#L150

Added line #L150 was not covered by tests
}

isRedisHealthy = true
isRedisHealthy = true
}
}

// Move into the cardinal directory
Expand Down Expand Up @@ -236,10 +242,14 @@ func startRedis(ctx context.Context, cfg *config.Config) error {
}
defer dockerClient.Close()

// Create context with cancel
ctx, cancel := context.WithCancel(ctx)

// Start Redis container
group.Go(func() error {
cfg.Detach = true
if err := dockerClient.Start(ctx, cfg, service.Redis); err != nil {
if err := dockerClient.Start(ctx, service.Redis); err != nil {
cancel()

Check warning on line 252 in cmd/world/cardinal/dev.go

View check run for this annotation

Codecov / codecov/patch

cmd/world/cardinal/dev.go#L252

Added line #L252 was not covered by tests
return eris.Wrap(err, "Encountered an error with Redis")
}
return nil
Expand All @@ -251,7 +261,8 @@ func startRedis(ctx context.Context, cfg *config.Config) error {
// 2) The parent context is canceled for whatever reason.
group.Go(func() error {
<-ctx.Done()
if err := dockerClient.Stop(cfg, service.Redis); err != nil {
// Using context background because cmd context is already done
if err := dockerClient.Stop(context.Background(), service.Redis); err != nil {
return err
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/world/cardinal/purge.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This command stop all Docker services and remove all Docker volumes.`,
}
defer dockerClient.Close()

err = dockerClient.Purge(cfg, service.Nakama, service.Cardinal, service.NakamaDB, service.Redis)
err = dockerClient.Purge(cmd.Context(), service.Nakama, service.Cardinal, service.NakamaDB, service.Redis)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/world/cardinal/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ This will restart the following Docker services:
}
defer dockerClient.Close()

err = dockerClient.Restart(cmd.Context(), cfg, service.Cardinal, service.Nakama)
err = dockerClient.Restart(cmd.Context(), service.Cardinal, service.Nakama)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/world/cardinal/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ This will start the following Docker services and its dependencies:

// Start the World Engine stack
group.Go(func() error {
if err := dockerClient.Start(ctx, cfg, service.NakamaDB,
if err := dockerClient.Start(ctx, service.NakamaDB,
service.Redis, service.Cardinal, service.Nakama); err != nil {
return eris.Wrap(err, "Encountered an error with Docker")
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/world/cardinal/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ This will stop the following Docker services:
}
defer dockerClient.Close()

err = dockerClient.Stop(cfg, service.Nakama, service.Cardinal, service.NakamaDB, service.Redis)
err = dockerClient.Stop(cmd.Context(), service.Nakama, service.Cardinal, service.NakamaDB, service.Redis)
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/world/evm/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ var startCmd = &cobra.Command{
cfg.Detach = false
cfg.Timeout = 0

err = dockerClient.Start(cmd.Context(), cfg, service.EVM)
err = dockerClient.Start(cmd.Context(), service.EVM)
if err != nil {
return fmt.Errorf("error starting %s docker container: %w", teacmd.DockerServiceEVM, err)
}

// Stop the DA service if it was started in dev mode
if cfg.DevDA {
err = dockerClient.Stop(cfg, service.CelestiaDevNet)
// using context background because cmd.Context() is already done
err = dockerClient.Stop(context.Background(), service.CelestiaDevNet)
if err != nil {
return eris.Wrap(err, "Failed to stop DA service")
}
Expand All @@ -80,7 +81,7 @@ func validateDevDALayer(ctx context.Context, cfg *config.Config, dockerClient *d
cfg.Detach = true
cfg.Timeout = -1
logger.Println("starting DA docker service for dev mode...")
if err := dockerClient.Start(ctx, cfg, service.CelestiaDevNet); err != nil {
if err := dockerClient.Start(ctx, service.CelestiaDevNet); err != nil {
return fmt.Errorf("error starting %s docker container: %w", daService, err)
}
logger.Println("started DA service...")
Expand Down
2 changes: 1 addition & 1 deletion cmd/world/evm/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var stopCmd = &cobra.Command{
}
defer dockerClient.Close()

err = dockerClient.Stop(cfg, service.EVM, service.CelestiaDevNet)
err = dockerClient.Stop(cmd.Context(), service.EVM, service.CelestiaDevNet)

Check warning on line 30 in cmd/world/evm/stop.go

View check run for this annotation

Codecov / codecov/patch

cmd/world/evm/stop.go#L30

Added line #L30 was not covered by tests
if err != nil {
return err
}
Expand Down
76 changes: 43 additions & 33 deletions common/docker/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ func (c *Client) Close() error {
return c.client.Close()
}

func (c *Client) Start(ctx context.Context, cfg *config.Config,
func (c *Client) Start(ctx context.Context,
serviceBuilders ...service.Builder) error {
defer func() {
if !cfg.Detach {
err := c.Stop(cfg, serviceBuilders...)
if !c.cfg.Detach {
err := c.Stop(context.Background(), serviceBuilders...)
if err != nil {
logger.Error("Failed to stop containers", err)
}
}
}()

namespace := cfg.DockerEnv["CARDINAL_NAMESPACE"]
namespace := c.cfg.DockerEnv["CARDINAL_NAMESPACE"]
err := c.createNetworkIfNotExists(ctx, namespace)
if err != nil {
return eris.Wrap(err, "Failed to create network")
Expand All @@ -64,7 +64,8 @@ func (c *Client) Start(ctx context.Context, cfg *config.Config,
// get all services
dockerServices := make([]service.Service, 0)
for _, sb := range serviceBuilders {
dockerServices = append(dockerServices, sb(cfg))
ds := sb(c.cfg)
dockerServices = append(dockerServices, ds)
}

// Pull all images before starting containers
Expand All @@ -73,67 +74,76 @@ func (c *Client) Start(ctx context.Context, cfg *config.Config,
return eris.Wrap(err, "Failed to pull images")
}

// Start all containers
for _, dockerService := range dockerServices {
// build image if needed
if cfg.Build && dockerService.Dockerfile != "" {
if err := c.buildImage(ctx, dockerService.Dockerfile, dockerService.BuildTarget, dockerService.Image); err != nil {
return eris.Wrap(err, "Failed to build image")
}
// Build all images before starting containers
if c.cfg.Build {
err = c.buildImages(ctx, dockerServices...)
if err != nil {
return eris.Wrap(err, "Failed to build images")

Check warning on line 81 in common/docker/client.go

View check run for this annotation

Codecov / codecov/patch

common/docker/client.go#L79-L81

Added lines #L79 - L81 were not covered by tests
}
}

// create container & start
if err := c.startContainer(ctx, dockerService); err != nil {
return eris.Wrap(err, "Failed to create container")
}
// Start all containers
err = c.processMultipleContainers(ctx, START, dockerServices...)
if err != nil {
return eris.Wrap(err, "Failed to start containers")

Check warning on line 88 in common/docker/client.go

View check run for this annotation

Codecov / codecov/patch

common/docker/client.go#L88

Added line #L88 was not covered by tests
}

// log containers if not detached
if !cfg.Detach {
if !c.cfg.Detach {
c.logMultipleContainers(ctx, dockerServices...)
}

return nil
}

func (c *Client) Stop(cfg *config.Config, serviceBuilders ...service.Builder) error {
ctx := context.Background()
func (c *Client) Stop(ctx context.Context, serviceBuilders ...service.Builder) error {
// get all services
dockerServices := make([]service.Service, 0)
for _, sb := range serviceBuilders {
dockerService := sb(cfg)
if err := c.stopContainer(ctx, dockerService.Name); err != nil {
return eris.Wrap(err, "Failed to stop container")
}
ds := sb(c.cfg)
dockerServices = append(dockerServices, ds)
}

// Stop all containers
err := c.processMultipleContainers(ctx, STOP, dockerServices...)
if err != nil {
return eris.Wrap(err, "Failed to stop containers")

Check warning on line 110 in common/docker/client.go

View check run for this annotation

Codecov / codecov/patch

common/docker/client.go#L110

Added line #L110 was not covered by tests
}

return nil
}

func (c *Client) Purge(cfg *config.Config, serviceBuilders ...service.Builder) error {
ctx := context.Background()
func (c *Client) Purge(ctx context.Context, serviceBuilders ...service.Builder) error {
// get all services
dockerServices := make([]service.Service, 0)
for _, sb := range serviceBuilders {
dockerService := sb(cfg)
if err := c.removeContainer(ctx, dockerService.Name); err != nil {
return eris.Wrap(err, "Failed to remove container")
}
ds := sb(c.cfg)
dockerServices = append(dockerServices, ds)
}

// remove all containers
err := c.processMultipleContainers(ctx, REMOVE, dockerServices...)
if err != nil {
return eris.Wrap(err, "Failed to remove containers")

Check warning on line 127 in common/docker/client.go

View check run for this annotation

Codecov / codecov/patch

common/docker/client.go#L127

Added line #L127 was not covered by tests
}

err := c.removeVolume(ctx, cfg.DockerEnv["CARDINAL_NAMESPACE"])
err = c.removeVolume(ctx, c.cfg.DockerEnv["CARDINAL_NAMESPACE"])
if err != nil {
return err
}

return nil
}

func (c *Client) Restart(ctx context.Context, cfg *config.Config,
func (c *Client) Restart(ctx context.Context,
serviceBuilders ...service.Builder) error {
// stop containers
err := c.Stop(cfg, serviceBuilders...)
err := c.Stop(ctx, serviceBuilders...)
if err != nil {
return err
}

return c.Start(ctx, cfg, serviceBuilders...)
return c.Start(ctx, serviceBuilders...)
}

func (c *Client) Exec(ctx context.Context, containerID string, cmd []string) (string, error) {
Expand Down
Loading

0 comments on commit ca1e9dd

Please sign in to comment.