func()

in internal/pkg/docker/orchestrator/orchestrator.go [490:552]


func (o *Orchestrator) waitForContainerDependencies(ctx context.Context, name string, definitions map[string]ContainerDefinition) error {
	var deps []string
	for depName, state := range definitions[name].DependsOn {
		deps = append(deps, fmt.Sprintf("%s->%s", depName, state))
	}
	logMsg := strings.Join(deps, ", ")
	fmt.Printf("Waiting for container %q dependencies: [%s]\n", name, color.Emphasize(logMsg))
	eg, ctx := errgroup.WithContext(ctx)
	for name, state := range definitions[name].DependsOn {
		name, state := name, state
		eg.Go(func() error {
			ctrId := o.containerID(name)
			ticker := time.NewTicker(700 * time.Millisecond)
			defer ticker.Stop()
			for {
				select {
				case <-ticker.C:
				case <-ctx.Done():
					return ctx.Err()
				}
				switch state {
				case ctrStateStart:
					return nil
				case ctrStateHealthy:
					healthy, err := o.docker.IsContainerHealthy(ctx, ctrId)
					if err != nil {
						return fmt.Errorf("wait for container %q to be healthy: %w", ctrId, err)
					}
					if healthy {
						log.Successf("Successfully dependency container %q reached healthy\n", ctrId)
						return nil
					}
				case ctrStateComplete:
					exitCode, err := o.docker.ContainerExitCode(ctx, ctrId)
					var errContainerNotExited *dockerengine.ErrContainerNotExited
					if errors.As(err, &errContainerNotExited) {
						continue
					}
					if err != nil {
						return fmt.Errorf("wait for container %q to complete: %w", ctrId, err)
					}
					log.Successf("%q's dependency container %q exited with code: %d\n", name, ctrId, exitCode)
					return nil
				case ctrStateSuccess:
					exitCode, err := o.docker.ContainerExitCode(ctx, ctrId)
					var errContainerNotExited *dockerengine.ErrContainerNotExited
					if errors.As(err, &errContainerNotExited) {
						continue
					}
					if err != nil {
						return fmt.Errorf("wait for container %q to success: %w", ctrId, err)
					}
					if exitCode != 0 {
						return fmt.Errorf("dependency container %q exited with non-zero exit code %d", ctrId, exitCode)
					}
					log.Successf("%q's dependency container %q exited with code: %d\n", name, ctrId, exitCode)
					return nil
				}
			}
		})
	}
	return eg.Wait()
}