don't run "removeContainers" in parallel as we follow dependency order

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2021-01-27 10:30:39 +01:00
parent 7d0e1dfc3c
commit 163f3b9a89
3 changed files with 14 additions and 32 deletions

View File

@ -35,7 +35,6 @@ import (
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"
"github.com/docker/compose-cli/api/compose" "github.com/docker/compose-cli/api/compose"
"github.com/docker/compose-cli/api/progress" "github.com/docker/compose-cli/api/progress"
@ -77,15 +76,11 @@ func (s *composeService) Create(ctx context.Context, project *types.Project, opt
orphans := observedState.filter(isNotService(project.ServiceNames()...)) orphans := observedState.filter(isNotService(project.ServiceNames()...))
if len(orphans) > 0 { if len(orphans) > 0 {
if opts.RemoveOrphans { if opts.RemoveOrphans {
eg, _ := errgroup.WithContext(ctx)
w := progress.ContextWriter(ctx) w := progress.ContextWriter(ctx)
err := s.removeContainers(ctx, w, eg, orphans) err := s.removeContainers(ctx, w, orphans)
if err != nil { if err != nil {
return err return err
} }
if eg.Wait() != nil {
return err
}
} else { } else {
logrus.Warnf("Found orphan containers (%s) for this project. If "+ logrus.Warnf("Found orphan containers (%s) for this project. If "+
"you removed or renamed this service in your compose "+ "you removed or renamed this service in your compose "+

View File

@ -33,7 +33,6 @@ import (
) )
func (s *composeService) Down(ctx context.Context, projectName string, options compose.DownOptions) error { func (s *composeService) Down(ctx context.Context, projectName string, options compose.DownOptions) error {
eg, _ := errgroup.WithContext(ctx)
w := progress.ContextWriter(ctx) w := progress.ContextWriter(ctx)
if options.Project == nil { if options.Project == nil {
@ -55,25 +54,21 @@ func (s *composeService) Down(ctx context.Context, projectName string, options c
err = InReverseDependencyOrder(ctx, options.Project, func(c context.Context, service types.ServiceConfig) error { err = InReverseDependencyOrder(ctx, options.Project, func(c context.Context, service types.ServiceConfig) error {
serviceContainers, others := containers.split(isService(service.Name)) serviceContainers, others := containers.split(isService(service.Name))
err := s.removeContainers(ctx, w, eg, serviceContainers) err := s.removeContainers(ctx, w, serviceContainers)
containers = others containers = others
return err return err
}) })
if err != nil {
return err
}
if options.RemoveOrphans { if options.RemoveOrphans && len(containers) > 0 {
err := s.removeContainers(ctx, w, eg, containers) err := s.removeContainers(ctx, w, containers)
if err != nil { if err != nil {
return err return err
} }
} }
if err != nil {
return err
}
err = eg.Wait()
if err != nil {
return err
}
networks, err := s.apiClient.NetworkList(ctx, moby.NetworkListOptions{ networks, err := s.apiClient.NetworkList(ctx, moby.NetworkListOptions{
Filters: filters.NewArgs( Filters: filters.NewArgs(
projectFilter(projectName), projectFilter(projectName),
@ -82,6 +77,8 @@ func (s *composeService) Down(ctx context.Context, projectName string, options c
if err != nil { if err != nil {
return err return err
} }
eg, _ := errgroup.WithContext(ctx)
for _, n := range networks { for _, n := range networks {
networkID := n.ID networkID := n.ID
networkName := n.Name networkName := n.Name
@ -89,7 +86,6 @@ func (s *composeService) Down(ctx context.Context, projectName string, options c
return s.ensureNetworkDown(ctx, networkID, networkName) return s.ensureNetworkDown(ctx, networkID, networkName)
}) })
} }
return eg.Wait() return eg.Wait()
} }
@ -108,15 +104,14 @@ func (s *composeService) stopContainers(ctx context.Context, w progress.Writer,
return nil return nil
} }
func (s *composeService) removeContainers(ctx context.Context, w progress.Writer, eg *errgroup.Group, containers []moby.Container) error { func (s *composeService) removeContainers(ctx context.Context, w progress.Writer, containers []moby.Container) error {
eg, _ := errgroup.WithContext(ctx)
for _, container := range containers { for _, container := range containers {
toDelete := container toDelete := container
eg.Go(func() error { eg.Go(func() error {
eventName := "Container " + getCanonicalContainerName(toDelete) eventName := "Container " + getCanonicalContainerName(toDelete)
w.Event(progress.StoppingEvent(eventName))
err := s.stopContainers(ctx, w, []moby.Container{container}) err := s.stopContainers(ctx, w, []moby.Container{container})
if err != nil { if err != nil {
w.Event(progress.ErrorMessageEvent(eventName, "Error while Stopping"))
return err return err
} }
w.Event(progress.RemovingEvent(eventName)) w.Event(progress.RemovingEvent(eventName))

View File

@ -19,17 +19,14 @@ package compose
import ( import (
"context" "context"
"github.com/compose-spec/compose-go/types"
moby "github.com/docker/docker/api/types" moby "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/docker/compose-cli/api/progress" "github.com/docker/compose-cli/api/progress"
"github.com/compose-spec/compose-go/types"
"golang.org/x/sync/errgroup"
) )
func (s *composeService) Stop(ctx context.Context, project *types.Project) error { func (s *composeService) Stop(ctx context.Context, project *types.Project, consumer compose.LogConsumer) error {
eg, _ := errgroup.WithContext(ctx)
w := progress.ContextWriter(ctx) w := progress.ContextWriter(ctx)
var containers Containers var containers Containers
@ -41,15 +38,10 @@ func (s *composeService) Stop(ctx context.Context, project *types.Project) error
return err return err
} }
err = InReverseDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error { return InReverseDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error {
serviceContainers, others := containers.split(isService(service.Name)) serviceContainers, others := containers.split(isService(service.Name))
err := s.stopContainers(ctx, w, serviceContainers) err := s.stopContainers(ctx, w, serviceContainers)
containers = others containers = others
return err return err
}) })
if err != nil {
return err
}
return eg.Wait()
} }