From 09e0fa94b8088916bf60806a0ac7407ec7bc721c Mon Sep 17 00:00:00 2001 From: Guillaume Lours Date: Sat, 19 Feb 2022 21:17:51 +0100 Subject: [PATCH 1/3] do not wait for dependencies with scale 0 Signed-off-by: Guillaume Lours --- pkg/compose/convergence.go | 6 ++++++ pkg/compose/convergence_test.go | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 24f051ee..aa81fb37 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -280,6 +280,12 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr // already managed by InDependencyOrder return nil } + if service, err := project.GetService(dep); err != nil { + return err + } else if service.Scale == 0 { + // don't wait for the dependency which configured to have 0 containers running + continue + } containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, dep) if err != nil { diff --git a/pkg/compose/convergence_test.go b/pkg/compose/convergence_test.go index 0b647c6b..69bc3908 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,21 @@ 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)) + }) +} From 4be38f84dfa6571d706081941c5b60b936123a7c Mon Sep 17 00:00:00 2001 From: Guillaume Lours Date: Sun, 20 Feb 2022 10:28:05 +0100 Subject: [PATCH 2/3] do not stop the dependencies wait process when reaching a dependency with service_started condition Signed-off-by: Guillaume Lours --- pkg/compose/convergence.go | 2 +- pkg/compose/convergence_test.go | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index aa81fb37..844cf331 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -278,7 +278,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr for dep, config := range dependencies { if config.Condition == types.ServiceConditionStarted { // already managed by InDependencyOrder - return nil + continue } if service, err := project.GetService(dep); err != nil { return err diff --git a/pkg/compose/convergence_test.go b/pkg/compose/convergence_test.go index 69bc3908..917af7af 100644 --- a/pkg/compose/convergence_test.go +++ b/pkg/compose/convergence_test.go @@ -202,4 +202,14 @@ func TestWaitDependencies(t *testing.T) { } 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)) + }) } From 64a9e4bf0139aa32b2bbd6a16d567ef35b26f90c Mon Sep 17 00:00:00 2001 From: Guillaume Lours Date: Sun, 20 Feb 2022 11:59:26 +0100 Subject: [PATCH 3/3] fix cyclomatic complexity of composeService.waitDependencies function Signed-off-by: Guillaume Lours --- pkg/compose/convergence.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 844cf331..2e6304f7 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -276,14 +276,9 @@ 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 - continue - } - if service, err := project.GetService(dep); err != nil { + if shouldWait, err := shouldWaitForDependency(dep, config, project); err != nil { return err - } else if service.Scale == 0 { - // don't wait for the dependency which configured to have 0 containers running + } else if !shouldWait { continue } @@ -340,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 {