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  }