package utils import ( "fmt" "sync" "time" ) const ( MAX_RESULTS = 200 ) type TimeFrameCounter struct { Name string Window time.Duration EndsAt time.Time StartedAt time.Time Count uint64 LastResults []uint64 } func (tfc *TimeFrameCounter) NewCall(t time.Time, incrCount uint64) { if t.Local().After(tfc.EndsAt) { // Window is finished ! tfc.LastResults = append(tfc.LastResults, tfc.Count) tfc.EndsAt = t.Add(tfc.Window) tfc.StartedAt = t if len(tfc.LastResults) > MAX_RESULTS { tfc.LastResults = tfc.LastResults[1:len(tfc.LastResults)] } tfc.Count = 0 } tfc.Count += incrCount } type DebugCounter struct { LastCallTime map[int64]time.Time TimeFrames map[int64][]TimeFrameCounter timeFramesCount map[int64]int mutex sync.Mutex } func NewDebugCounter(chains []int64, timeFrames ...time.Duration) *DebugCounter { t := time.Now() r := new(DebugCounter) r.mutex = sync.Mutex{} r.timeFramesCount = make(map[int64]int, len(chains)) r.LastCallTime = make(map[int64]time.Time, len(chains)) r.TimeFrames = make(map[int64][]TimeFrameCounter, len(chains)) for _, chain := range chains { tfs := make([]TimeFrameCounter, len(timeFrames)) for i, tf := range timeFrames { tfs[i] = TimeFrameCounter{ Name: tf.String(), Window: tf, StartedAt: t, EndsAt: t.Add(tf), } } r.TimeFrames[chain] = tfs r.timeFramesCount[chain] = len(tfs) r.LastCallTime[chain] = t } return r } func (cc *DebugCounter) Add(chain int64) { cc.AddFor(chain, 1) } func (cc *DebugCounter) AddFor(chain int64, incrCount uint64) { i := 0 t := time.Now() cc.mutex.Lock() cc.LastCallTime[chain] = t for i < cc.timeFramesCount[chain] { cc.TimeFrames[chain][i].NewCall(t, incrCount) i++ } cc.mutex.Unlock() } func (cc *DebugCounter) StatusChain(chain int64) string { _x := cc.TimeFrames[chain] x := _x[len(_x)-1] return fmt.Sprintf("count=%d range=(%s,%s)", x.Count, x.StartedAt.UTC().String(), x.EndsAt.UTC().String()) } func (cc *DebugCounter) StatusChainIndexOf(index int, chain int64) string { x := cc.TimeFrames[chain][index] rate := float64(x.Count) / x.Window.Seconds() return fmt.Sprintf("%f", rate) }