statsCollector.publishers must be protected to prevent
modifications during the iteration in run().
Being locked for a long time is bad, so pairs of containers &
publishers (pointers) are copied to release the lock fast.
Signed-off-by: Anton Tiurin <noxiouz@yandex.ru>
| ... | ... |
@@ -76,22 +76,42 @@ func (s *statsCollector) unsubscribe(c *Container, ch chan interface{}) {
|
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
func (s *statsCollector) run() {
|
| 79 |
+ type publishersPair struct {
|
|
| 80 |
+ container *Container |
|
| 81 |
+ publisher *pubsub.Publisher |
|
| 82 |
+ } |
|
| 83 |
+ // we cannot determine the capacity here. |
|
| 84 |
+ // it will grow enough in first iteration |
|
| 85 |
+ var pairs []publishersPair |
|
| 86 |
+ |
|
| 79 | 87 |
for range time.Tick(s.interval) {
|
| 88 |
+ systemUsage, err := s.getSystemCpuUsage() |
|
| 89 |
+ if err != nil {
|
|
| 90 |
+ logrus.Errorf("collecting system cpu usage: %v", err)
|
|
| 91 |
+ continue |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ // it does not make sense in the first iteration, |
|
| 95 |
+ // but saves allocations in further iterations |
|
| 96 |
+ pairs = pairs[:0] |
|
| 97 |
+ |
|
| 98 |
+ s.m.Lock() |
|
| 80 | 99 |
for container, publisher := range s.publishers {
|
| 81 |
- systemUsage, err := s.getSystemCpuUsage() |
|
| 82 |
- if err != nil {
|
|
| 83 |
- logrus.Errorf("collecting system cpu usage for %s: %v", container.ID, err)
|
|
| 84 |
- continue |
|
| 85 |
- } |
|
| 86 |
- stats, err := container.Stats() |
|
| 100 |
+ // copy pointers here to release the lock ASAP |
|
| 101 |
+ pairs = append(pairs, publishersPair{container, publisher})
|
|
| 102 |
+ } |
|
| 103 |
+ s.m.Unlock() |
|
| 104 |
+ |
|
| 105 |
+ for _, pair := range pairs {
|
|
| 106 |
+ stats, err := pair.container.Stats() |
|
| 87 | 107 |
if err != nil {
|
| 88 | 108 |
if err != execdriver.ErrNotRunning {
|
| 89 |
- logrus.Errorf("collecting stats for %s: %v", container.ID, err)
|
|
| 109 |
+ logrus.Errorf("collecting stats for %s: %v", pair.container.ID, err)
|
|
| 90 | 110 |
} |
| 91 | 111 |
continue |
| 92 | 112 |
} |
| 93 | 113 |
stats.SystemUsage = systemUsage |
| 94 |
- publisher.Publish(stats) |
|
| 114 |
+ pair.publisher.Publish(stats) |
|
| 95 | 115 |
} |
| 96 | 116 |
} |
| 97 | 117 |
} |