github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/counters/topics.go (about) 1 package counters 2 3 import ( 4 "database/sql" 5 "sync/atomic" 6 7 c "github.com/Azareal/Gosora/common" 8 qgen "github.com/Azareal/Gosora/query_gen" 9 "github.com/pkg/errors" 10 ) 11 12 var TopicCounter *DefaultTopicCounter 13 14 type DefaultTopicCounter struct { 15 buckets [2]int64 16 currentBucket int64 17 18 insert *sql.Stmt 19 } 20 21 func NewTopicCounter() (*DefaultTopicCounter, error) { 22 acc := qgen.NewAcc() 23 co := &DefaultTopicCounter{ 24 currentBucket: 0, 25 insert: acc.Insert("topicchunks").Columns("count,createdAt").Fields("?,UTC_TIMESTAMP()").Prepare(), 26 } 27 c.Tasks.FifteenMin.Add(co.Tick) 28 //c.Tasks.Sec.Add(co.Tick) 29 c.Tasks.Shutdown.Add(co.Tick) 30 return co, acc.FirstError() 31 } 32 33 func (co *DefaultTopicCounter) Tick() (e error) { 34 oldBucket := co.currentBucket 35 var nextBucket int64 // 0 36 if co.currentBucket == 0 { 37 nextBucket = 1 38 } 39 atomic.AddInt64(&co.buckets[oldBucket], co.buckets[nextBucket]) 40 atomic.StoreInt64(&co.buckets[nextBucket], 0) 41 atomic.StoreInt64(&co.currentBucket, nextBucket) 42 43 previousViewChunk := co.buckets[oldBucket] 44 atomic.AddInt64(&co.buckets[oldBucket], -previousViewChunk) 45 e = co.insertChunk(previousViewChunk) 46 if e != nil { 47 return errors.Wrap(errors.WithStack(e), "topics counter") 48 } 49 return nil 50 } 51 52 func (co *DefaultTopicCounter) Bump() { 53 atomic.AddInt64(&co.buckets[co.currentBucket], 1) 54 } 55 56 func (co *DefaultTopicCounter) insertChunk(count int64) error { 57 if count == 0 { 58 return nil 59 } 60 c.DebugLogf("Inserting a topicchunk with a count of %d", count) 61 _, e := co.insert.Exec(count) 62 return e 63 }