Quellcode durchsuchen

Merge pull request #9192 from glours/wait-and-scale-0

Wait and scale 0
Ulysses Souza vor 3 Jahren
Ursprung
Commit
8a9498c571
2 geänderte Dateien mit 47 neuen und 3 gelöschten Zeilen
  1. 18 3
      pkg/compose/convergence.go
  2. 29 0
      pkg/compose/convergence_test.go

+ 18 - 3
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 {

+ 29 - 0
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))
+	})
+}