Skip to content

Commit 20edfa4

Browse files
authored
Fix send on closed channel panic (#8470)
When the performance data is out of order, channel should be closed by the producer, but not consumer or other thread.
1 parent 57fd7f5 commit 20edfa4

File tree

1 file changed

+14
-10
lines changed
  • lib/apiservers/engine/backends/convert

1 file changed

+14
-10
lines changed

lib/apiservers/engine/backends/convert/stats.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (cs *ContainerStats) Listen() *io.PipeWriter {
134134
doc := json.NewEncoder(cs.config.Out)
135135

136136
// channel to transfer metric from decoder to encoder
137-
metric := make(chan performance.VMMetrics)
137+
metric := make(chan *types.StatsJSON)
138138

139139
// if we aren't streaming and the container is not running, then create an empty
140140
// docker stat to return
@@ -145,7 +145,6 @@ func (cs *ContainerStats) Listen() *io.PipeWriter {
145145
// go routine to stop on Context.Cancel
146146
go func() {
147147
<-cs.config.Ctx.Done()
148-
close(metric)
149148
cs.Stop()
150149
}()
151150

@@ -155,6 +154,7 @@ func (cs *ContainerStats) Listen() *io.PipeWriter {
155154
for {
156155
select {
157156
case <-cs.config.Ctx.Done():
157+
close(metric)
158158
return
159159
default:
160160
for dec.More() {
@@ -163,10 +163,20 @@ func (cs *ContainerStats) Listen() *io.PipeWriter {
163163
if err != nil {
164164
log.Errorf("container metric decoding error for container(%s): %s", cs.config.ContainerID, err)
165165
cs.config.Cancel()
166+
close(metric)
167+
return
168+
}
169+
// convert the Stat to docker struct
170+
stat, err := cs.ToContainerStats(&vmm)
171+
if err != nil {
172+
log.Errorf("container metric conversion error for container(%s): %s", cs.config.ContainerID, err)
173+
cs.config.Cancel()
174+
close(metric)
175+
return
166176
}
167177
// send the decoded metric for transform and encoding
168178
if cs.IsListening() {
169-
metric <- vmm
179+
metric <- stat
170180
}
171181
}
172182
}
@@ -183,13 +193,7 @@ func (cs *ContainerStats) Listen() *io.PipeWriter {
183193
case <-cs.config.Ctx.Done():
184194
ticker.Stop()
185195
return
186-
case nm := <-metric:
187-
// convert the Stat to docker struct
188-
stat, err := cs.ToContainerStats(&nm)
189-
if err != nil {
190-
log.Errorf("container metric conversion error for container(%s): %s", cs.config.ContainerID, err)
191-
cs.config.Cancel()
192-
}
196+
case stat := <-metric:
193197
if stat != nil {
194198
cs.preDockerStat = stat
195199
}

0 commit comments

Comments
 (0)