metric: update date_counter

This commit is contained in:
fatedier 2017-03-27 03:39:32 +08:00
parent aa185eb9f3
commit 6a95a63fd4

View File

@ -26,7 +26,6 @@ type DateCounter interface {
Dec(int64)
Snapshot() DateCounter
Clear()
Close()
}
func NewDateCounter(reserveDays int64) DateCounter {
@ -40,24 +39,26 @@ type StandardDateCounter struct {
reserveDays int64
counts []int64
closeCh chan struct{}
closed bool
mu sync.Mutex
lastUpdateDate time.Time
mu sync.Mutex
}
func newStandardDateCounter(reserveDays int64) *StandardDateCounter {
now := time.Now()
now = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
s := &StandardDateCounter{
reserveDays: reserveDays,
counts: make([]int64, reserveDays),
closeCh: make(chan struct{}),
reserveDays: reserveDays,
counts: make([]int64, reserveDays),
lastUpdateDate: now,
}
s.startRotateWorker()
return s
}
func (c *StandardDateCounter) TodayCount() int64 {
c.mu.Lock()
defer c.mu.Unlock()
c.rotate(time.Now())
return c.counts[0]
}
@ -69,6 +70,7 @@ func (c *StandardDateCounter) GetLastDaysCount(lastdays int64) []int64 {
c.mu.Lock()
defer c.mu.Unlock()
c.rotate(time.Now())
for i := 0; i < int(lastdays); i++ {
counts[i] = c.counts[i]
}
@ -78,12 +80,14 @@ func (c *StandardDateCounter) GetLastDaysCount(lastdays int64) []int64 {
func (c *StandardDateCounter) Inc(count int64) {
c.mu.Lock()
defer c.mu.Unlock()
c.rotate(time.Now())
c.counts[0] += count
}
func (c *StandardDateCounter) Dec(count int64) {
c.mu.Lock()
defer c.mu.Unlock()
c.rotate(time.Now())
c.counts[0] -= count
}
@ -108,50 +112,26 @@ func (c *StandardDateCounter) Clear() {
}
}
func (c *StandardDateCounter) Close() {
c.mu.Lock()
defer c.mu.Unlock()
if !c.closed {
close(c.closeCh)
c.closed = true
}
}
// rotate
// Must hold the lock before calling this function.
func (c *StandardDateCounter) rotate(now time.Time) {
now = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
days := int(now.Sub(c.lastUpdateDate).Hours() / 24)
func (c *StandardDateCounter) rotate() {
c.mu.Lock()
defer c.mu.Unlock()
defer func() {
c.lastUpdateDate = now
}()
if days <= 0 {
return
} else if days >= 7 {
c.counts = make([]int64, c.reserveDays)
return
}
newCounts := make([]int64, c.reserveDays)
for i := 1; i < int(c.reserveDays-1); i++ {
newCounts[i] = c.counts[i+1]
for i := days; i < int(c.reserveDays); i++ {
newCounts[i] = c.counts[i-days]
}
c.counts = newCounts
}
func (c *StandardDateCounter) startRotateWorker() {
now := time.Now()
nextDayTimeStr := now.Add(24 * time.Hour).Format("20060102")
nextDay, _ := time.Parse("20060102", nextDayTimeStr)
d := nextDay.Sub(now)
firstTimer := time.NewTimer(d)
rotateTicker := time.NewTicker(24 * time.Hour)
go func() {
for {
select {
case <-firstTimer.C:
firstTimer.Stop()
rotateTicker.Stop()
rotateTicker = time.NewTicker(24 * time.Hour)
c.rotate()
case <-rotateTicker.C:
c.rotate()
case <-c.closeCh:
break
}
}
firstTimer.Stop()
rotateTicker.Stop()
}()
}