in local-container-endpoints/handlers/metadata.go [137:176]
func (service *MetadataService) taskStatsResponse(w http.ResponseWriter, identifier string, callerIP string) error {
timeout, _ := time.ParseDuration(config.HTTPTimeoutDuration)
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
containers, err := service.dockerClient.ContainerList(ctx)
if err != nil {
return err
}
response := make(map[string]types.Stats)
statsChan := make(chan dockerStats, len(containers))
for _, container := range containers {
go service.getContainerStatsWithChannel(ctx, statsChan, container.ID)
}
for range containers {
select {
case <-ctx.Done():
return ctx.Err()
case stats := <-statsChan:
if stats.err != nil {
// cancel the context
cancel()
// Question for @sharanyad and @clareliguori: it's safe to return here, right?
// Any remaining goroutines will write to the buffered channel, and terminate.
// Then the buffered channel will get garbage collected.
// Also calling cancel() ends the context,
// so none of the Docker API requests can get stuck.
// This also applies for the above case where we return ctx.Err().
return stats.err
}
response[stats.containerID] = *stats.stats
}
}
writeJSONResponse(w, response)
return nil
}