qps_monitor.go (52 lines of code) (raw):

package ali_mns import ( "sync/atomic" "time" ) type QPSMonitor struct { qpsLimit int32 latestIndex int32 delaySecond int32 totalQueries []int32 } func (p *QPSMonitor) Pulse() { index := p.Update() atomic.AddInt32(&p.totalQueries[index], 1) } func (p *QPSMonitor) Update() int32 { index := int32(time.Now().Second()) % p.delaySecond if p.latestIndex != index { atomic.StoreInt32(&p.latestIndex, index) atomic.StoreInt32(&p.totalQueries[p.latestIndex], 0) } return index } func (p *QPSMonitor) QPS() int32 { var totalCount int32 = 0 for i, queryCount := range p.totalQueries { if int32(i) != p.latestIndex { totalCount += queryCount } } return totalCount / (p.delaySecond - 1) } func (p *QPSMonitor) checkQPS() { p.Pulse() if p.qpsLimit > 0 { for p.QPS() > p.qpsLimit { time.Sleep(time.Millisecond * 10) p.Update() } } } func NewQPSMonitor(delaySecond int32, qpsLimit int32) *QPSMonitor { if delaySecond < 5 { delaySecond = 5 } monitor := QPSMonitor{ qpsLimit: qpsLimit, delaySecond: delaySecond, totalQueries: make([]int32, delaySecond), } return &monitor }