cli/command/container: runStats(): move code to where it's used

The monitorContainerEvents and getContainerList closures where only
used when collecting "all" containers, so let's define them in that
branch of the code.

Also move some of the other variables closer to where they're used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-12-20 11:54:12 +01:00
parent 5ed6c128e8
commit 633ba88c26
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
1 changed files with 47 additions and 47 deletions

View File

@ -60,37 +60,8 @@ func NewStatsCommand(dockerCLI command.Cli) *cobra.Command {
// //
//nolint:gocyclo //nolint:gocyclo
func runStats(ctx context.Context, dockerCLI command.Cli, options *statsOptions) error { func runStats(ctx context.Context, dockerCLI command.Cli, options *statsOptions) error {
showAll := len(options.containers) == 0
closeChan := make(chan error)
apiClient := dockerCLI.Client() apiClient := dockerCLI.Client()
// monitorContainerEvents watches for container creation and removal (only
// used when calling `docker stats` without arguments).
monitorContainerEvents := func(started chan<- struct{}, c chan events.Message, stopped <-chan struct{}) {
f := filters.NewArgs()
f.Add("type", string(events.ContainerEventType))
eventChan, errChan := apiClient.Events(ctx, types.EventsOptions{
Filters: f,
})
// Whether we successfully subscribed to eventChan or not, we can now
// unblock the main goroutine.
close(started)
defer close(c)
for {
select {
case <-stopped:
return
case event := <-eventChan:
c <- event
case err := <-errChan:
closeChan <- err
return
}
}
}
// Get the daemonOSType if not set already // Get the daemonOSType if not set already
if daemonOSType == "" { if daemonOSType == "" {
sv, err := apiClient.ServerVersion(ctx) sv, err := apiClient.ServerVersion(ctx)
@ -102,26 +73,10 @@ func runStats(ctx context.Context, dockerCLI command.Cli, options *statsOptions)
// waitFirst is a WaitGroup to wait first stat data's reach for each container // waitFirst is a WaitGroup to wait first stat data's reach for each container
waitFirst := &sync.WaitGroup{} waitFirst := &sync.WaitGroup{}
closeChan := make(chan error)
cStats := stats{} cStats := stats{}
// getContainerList simulates creation event for all previously existing
// containers (only used when calling `docker stats` without arguments).
getContainerList := func() {
cs, err := apiClient.ContainerList(ctx, container.ListOptions{
All: options.all,
})
if err != nil {
closeChan <- err
}
for _, ctr := range cs {
s := NewStats(ctr.ID[:12])
if cStats.add(s) {
waitFirst.Add(1)
go collect(ctx, s, apiClient, !options.noStream, waitFirst)
}
}
}
showAll := len(options.containers) == 0
if showAll { if showAll {
// If no names were specified, start a long-running goroutine which // If no names were specified, start a long-running goroutine which
// monitors container events. We make sure we're subscribed before // monitors container events. We make sure we're subscribed before
@ -153,6 +108,51 @@ func runStats(ctx context.Context, dockerCLI command.Cli, options *statsOptions)
}) })
} }
// monitorContainerEvents watches for container creation and removal (only
// used when calling `docker stats` without arguments).
monitorContainerEvents := func(started chan<- struct{}, c chan events.Message, stopped <-chan struct{}) {
f := filters.NewArgs()
f.Add("type", string(events.ContainerEventType))
eventChan, errChan := apiClient.Events(ctx, types.EventsOptions{
Filters: f,
})
// Whether we successfully subscribed to eventChan or not, we can now
// unblock the main goroutine.
close(started)
defer close(c)
for {
select {
case <-stopped:
return
case event := <-eventChan:
c <- event
case err := <-errChan:
closeChan <- err
return
}
}
}
// getContainerList simulates creation event for all previously existing
// containers (only used when calling `docker stats` without arguments).
getContainerList := func() {
cs, err := apiClient.ContainerList(ctx, container.ListOptions{
All: options.all,
})
if err != nil {
closeChan <- err
}
for _, ctr := range cs {
s := NewStats(ctr.ID[:12])
if cStats.add(s) {
waitFirst.Add(1)
go collect(ctx, s, apiClient, !options.noStream, waitFirst)
}
}
}
eventChan := make(chan events.Message) eventChan := make(chan events.Message)
go eh.Watch(eventChan) go eh.Watch(eventChan)
stopped := make(chan struct{}) stopped := make(chan struct{})