Skip to content

Commit

Permalink
Fix (rare) race in ZoneStats
Browse files Browse the repository at this point in the history
  • Loading branch information
abh committed Aug 9, 2015
1 parent 623638d commit feb0498
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 35 deletions.
50 changes: 16 additions & 34 deletions zone_stats.go
Expand Up @@ -2,16 +2,14 @@ package main

import (
"sort"
"sync"
)

type zoneLabelStats struct {
pos int
rotated bool
log []string
in chan string
out chan []string
reset chan bool
close chan bool
mu sync.Mutex
}

type labelStats []labelStat
Expand All @@ -30,48 +28,31 @@ type labelStat struct {

func NewZoneLabelStats(size int) *zoneLabelStats {
zs := &zoneLabelStats{
log: make([]string, size),
in: make(chan string, 100),
out: make(chan []string),
reset: make(chan bool),
close: make(chan bool),
log: make([]string, size),
}
go zs.receiver()
return zs
}

func (zs *zoneLabelStats) receiver() {

for {
select {
case new := <-zs.in:
zs.add(new)
case zs.out <- zs.log:
case <-zs.reset:
zs.pos = 0
zs.log = make([]string, len(zs.log))
zs.rotated = false
case <-zs.close:
close(zs.in)
return
}
}

}

func (zs *zoneLabelStats) Close() {
zs.close <- true
zs.log = []string{}
}

func (zs *zoneLabelStats) Reset() {
zs.reset <- true
zs.mu.Lock()
defer zs.mu.Unlock()
zs.pos = 0
zs.log = make([]string, len(zs.log))
zs.rotated = false
}

func (zs *zoneLabelStats) Add(l string) {
zs.in <- l
zs.add(l)
}

func (zs *zoneLabelStats) add(l string) {
zs.mu.Lock()
defer zs.mu.Unlock()

zs.log[zs.pos] = l
zs.pos++
if zs.pos+1 > len(zs.log) {
Expand Down Expand Up @@ -100,10 +81,11 @@ func (zs *zoneLabelStats) TopCounts(n int) labelStats {
}

func (zs *zoneLabelStats) Counts() map[string]int {
log := (<-zs.out)
zs.mu.Lock()
defer zs.mu.Unlock()

counts := make(map[string]int)
for i, l := range log {
for i, l := range zs.log {
if zs.rotated == false && i >= zs.pos {
break
}
Expand Down
2 changes: 1 addition & 1 deletion zone_stats_test.go
Expand Up @@ -23,7 +23,7 @@ func (s *ZoneStatsSuite) TestZoneStats(c *C) {
c.Check(co["foo"], Equals, 1)
zs.Add("foo")
co = zs.Counts()
// close

c.Check(co["abc"], Equals, 1)
c.Check(co["foo"], Equals, 2)
zs.Close()
Expand Down

0 comments on commit feb0498

Please sign in to comment.