Skip to content

Commit 7dfa1d0

Browse files
authored
Merge pull request #2355 from tanenbaum/bug/container_deadlock
Fix container `OnDemandHousekeeping` blocking on stop channel.
2 parents 99a08cd + cd5f6d7 commit 7dfa1d0

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

manager/container.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ type containerData struct {
8181
logUsage bool
8282

8383
// Tells the container to stop.
84-
stop chan bool
84+
stop chan struct{}
8585

8686
// Tells the container to immediately collect stats
8787
onDemandChan chan chan struct{}
@@ -114,7 +114,7 @@ func (c *containerData) Stop() error {
114114
if err != nil {
115115
return err
116116
}
117-
c.stop <- true
117+
close(c.stop)
118118
return nil
119119
}
120120

@@ -383,7 +383,7 @@ func newContainerData(containerName string, memoryCache *memory.InMemoryCache, h
383383
allowDynamicHousekeeping: allowDynamicHousekeeping,
384384
logUsage: logUsage,
385385
loadAvg: -1.0, // negative value indicates uninitialized.
386-
stop: make(chan bool, 1),
386+
stop: make(chan struct{}),
387387
collectorManager: collectorManager,
388388
onDemandChan: make(chan chan struct{}, 100),
389389
clock: clock,

manager/container_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,28 @@ func TestConcurrentOnDemandHousekeeping(t *testing.T) {
287287
checkNumStats(t, memoryCache, 1)
288288
mockHandler.AssertExpectations(t)
289289
}
290+
291+
func TestOnDemandHousekeepingReturnsAfterStopped(t *testing.T) {
292+
statsList := itest.GenerateRandomStats(1, 4, 1*time.Second)
293+
stats := statsList[0]
294+
295+
cd, mockHandler, memoryCache, fakeClock := newTestContainerData(t)
296+
mockHandler.On("GetStats").Return(stats, nil)
297+
298+
// trigger housekeeping update
299+
go cd.OnDemandHousekeeping(0 * time.Second)
300+
cd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping)
301+
302+
checkNumStats(t, memoryCache, 1)
303+
304+
fakeClock.Step(2 * time.Second)
305+
306+
cd.Stop()
307+
// housekeeping tick should detect stop and not store any more metrics
308+
assert.False(t, cd.housekeepingTick(fakeClock.NewTimer(time.Minute).C(), testLongHousekeeping))
309+
fakeClock.Step(1 * time.Second)
310+
// on demand housekeeping should not block and return
311+
cd.OnDemandHousekeeping(-1 * time.Second)
312+
313+
mockHandler.AssertExpectations(t)
314+
}

0 commit comments

Comments
 (0)