Merge pull request #12714 from noxiouz/fix_race_stats_collector

statsCollector: fix data race in run()
This commit is contained in:
Jessie Frazelle 2015-04-27 10:57:56 -05:00
Родитель 02d73d910f 11a5f1af01
Коммит 9f684c8592
1 изменённых файлов: 28 добавлений и 8 удалений

Просмотреть файл

@ -76,22 +76,42 @@ func (s *statsCollector) unsubscribe(c *Container, ch chan interface{}) {
}
func (s *statsCollector) run() {
type publishersPair struct {
container *Container
publisher *pubsub.Publisher
}
// we cannot determine the capacity here.
// it will grow enough in first iteration
var pairs []publishersPair
for range time.Tick(s.interval) {
systemUsage, err := s.getSystemCpuUsage()
if err != nil {
logrus.Errorf("collecting system cpu usage: %v", err)
continue
}
// it does not make sense in the first iteration,
// but saves allocations in further iterations
pairs = pairs[:0]
s.m.Lock()
for container, publisher := range s.publishers {
systemUsage, err := s.getSystemCpuUsage()
if err != nil {
logrus.Errorf("collecting system cpu usage for %s: %v", container.ID, err)
continue
}
stats, err := container.Stats()
// copy pointers here to release the lock ASAP
pairs = append(pairs, publishersPair{container, publisher})
}
s.m.Unlock()
for _, pair := range pairs {
stats, err := pair.container.Stats()
if err != nil {
if err != execdriver.ErrNotRunning {
logrus.Errorf("collecting stats for %s: %v", container.ID, err)
logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err)
}
continue
}
stats.SystemUsage = systemUsage
publisher.Publish(stats)
pair.publisher.Publish(stats)
}
}
}