diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 24f051ee2..2e6304f7c 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -276,9 +276,10 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr eg, _ := errgroup.WithContext(ctx) w := progress.ContextWriter(ctx) for dep, config := range dependencies { - if config.Condition == types.ServiceConditionStarted { - // already managed by InDependencyOrder - return nil + if shouldWait, err := shouldWaitForDependency(dep, config, project); err != nil { + return err + } else if !shouldWait { + continue } containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, dep) @@ -334,6 +335,20 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr return eg.Wait() } +func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceDependency, project *types.Project) (bool, error) { + if dependencyConfig.Condition == types.ServiceConditionStarted { + // already managed by InDependencyOrder + return false, nil + } + if service, err := project.GetService(serviceName); err != nil { + return false, err + } else if service.Scale == 0 { + // don't wait for the dependency which configured to have 0 containers running + return false, nil + } + return true, nil +} + func nextContainerNumber(containers []moby.Container) (int, error) { max := 0 for _, c := range containers { diff --git a/pkg/compose/convergence_test.go b/pkg/compose/convergence_test.go index 0b647c6b4..917af7af9 100644 --- a/pkg/compose/convergence_test.go +++ b/pkg/compose/convergence_test.go @@ -19,6 +19,7 @@ package compose import ( "context" "fmt" + "strings" "testing" "github.com/compose-spec/compose-go/types" @@ -184,3 +185,31 @@ func TestServiceLinks(t *testing.T) { assert.Equal(t, links[2], "testProject-web-1:testProject-web-1") }) } + +func TestWaitDependencies(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + api := mocks.NewMockAPIClient(mockCtrl) + tested.apiClient = api + + t.Run("should skip dependencies with scale 0", func(t *testing.T) { + dbService := types.ServiceConfig{Name: "db", Scale: 0} + redisService := types.ServiceConfig{Name: "redis", Scale: 0} + project := types.Project{Name: strings.ToLower(testProject), Services: []types.ServiceConfig{dbService, redisService}} + dependencies := types.DependsOnConfig{ + "db": {Condition: ServiceConditionRunningOrHealthy}, + "redis": {Condition: ServiceConditionRunningOrHealthy}, + } + assert.NilError(t, tested.waitDependencies(context.Background(), &project, dependencies)) + }) + t.Run("should skip dependencies with condition service_started", func(t *testing.T) { + dbService := types.ServiceConfig{Name: "db", Scale: 1} + redisService := types.ServiceConfig{Name: "redis", Scale: 1} + project := types.Project{Name: strings.ToLower(testProject), Services: []types.ServiceConfig{dbService, redisService}} + dependencies := types.DependsOnConfig{ + "db": {Condition: types.ServiceConditionStarted}, + "redis": {Condition: types.ServiceConditionStarted}, + } + assert.NilError(t, tested.waitDependencies(context.Background(), &project, dependencies)) + }) +}