77291e4b44
Add unlisted LogLongTick developer setting. Rearrange the order of the shutdown signal handler to figure out where it might fail.
178 lines
2.8 KiB
Go
178 lines
2.8 KiB
Go
package counters
|
|
|
|
import (
|
|
"database/sql"
|
|
"sync/atomic"
|
|
|
|
c "github.com/Azareal/Gosora/common"
|
|
qgen "github.com/Azareal/Gosora/query_gen"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
var LangViewCounter *DefaultLangViewCounter
|
|
|
|
var langCodes = []string{
|
|
"unknown",
|
|
"",
|
|
"af",
|
|
"ar",
|
|
"az",
|
|
"be",
|
|
"bg",
|
|
"bs",
|
|
"ca",
|
|
"cs",
|
|
"cy",
|
|
"da",
|
|
"de",
|
|
"dv",
|
|
"el",
|
|
"en",
|
|
"eo",
|
|
"es",
|
|
"et",
|
|
"eu",
|
|
"fa",
|
|
"fi",
|
|
"fo",
|
|
"fr",
|
|
"gl",
|
|
"gu",
|
|
"he",
|
|
"hi",
|
|
"hr",
|
|
"hu",
|
|
"hy",
|
|
"id",
|
|
"is",
|
|
"it",
|
|
"ja",
|
|
"ka",
|
|
"kk",
|
|
"kn",
|
|
"ko",
|
|
"kok",
|
|
"kw",
|
|
"ky",
|
|
"lt",
|
|
"lv",
|
|
"mi",
|
|
"mk",
|
|
"mn",
|
|
"mr",
|
|
"ms",
|
|
"mt",
|
|
"nb",
|
|
"nl",
|
|
"nn",
|
|
"ns",
|
|
"pa",
|
|
"pl",
|
|
"ps",
|
|
"pt",
|
|
"qu",
|
|
"ro",
|
|
"ru",
|
|
"sa",
|
|
"se",
|
|
"sk",
|
|
"sl",
|
|
"sq",
|
|
"sr",
|
|
"sv",
|
|
"sw",
|
|
"syr",
|
|
"ta",
|
|
"te",
|
|
"th",
|
|
"tl",
|
|
"tn",
|
|
"tr",
|
|
"tt",
|
|
"ts",
|
|
"uk",
|
|
"ur",
|
|
"uz",
|
|
"vi",
|
|
"xh",
|
|
"zh",
|
|
"zu",
|
|
}
|
|
|
|
type DefaultLangViewCounter struct {
|
|
//buckets []*MutexCounterBucket //[OSID]count
|
|
buckets []int64 //[OSID]count
|
|
codesToIndices map[string]int
|
|
|
|
insert *sql.Stmt
|
|
}
|
|
|
|
func NewDefaultLangViewCounter(acc *qgen.Accumulator) (*DefaultLangViewCounter, error) {
|
|
codesToIndices := make(map[string]int, len(langCodes))
|
|
for index, code := range langCodes {
|
|
codesToIndices[code] = index
|
|
}
|
|
co := &DefaultLangViewCounter{
|
|
buckets: make([]int64, len(langCodes)),
|
|
codesToIndices: codesToIndices,
|
|
insert: acc.Insert("viewchunks_langs").Columns("count,createdAt,lang").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
|
|
}
|
|
|
|
c.Tasks.FifteenMin.Add(co.Tick)
|
|
//c.Tasks.Sec.Add(co.Tick)
|
|
c.Tasks.Shutdown.Add(co.Tick)
|
|
return co, acc.FirstError()
|
|
}
|
|
|
|
func (co *DefaultLangViewCounter) Tick() error {
|
|
for id := 0; id < len(co.buckets); id++ {
|
|
count := atomic.SwapInt64(&co.buckets[id], 0)
|
|
e := co.insertChunk(count, id) // TODO: Bulk insert for speed?
|
|
if e != nil {
|
|
return errors.Wrap(errors.WithStack(e), "langview counter")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (co *DefaultLangViewCounter) insertChunk(count int64, id int) error {
|
|
if count == 0 {
|
|
return nil
|
|
}
|
|
langCode := langCodes[id]
|
|
if langCode == "" {
|
|
langCode = "none"
|
|
}
|
|
c.DebugLogf("Inserting a vchunk with a count of %d for lang %s (%d)", count, langCode, id)
|
|
_, e := co.insert.Exec(count, langCode)
|
|
return e
|
|
}
|
|
|
|
func (co *DefaultLangViewCounter) Bump(langCode string) (validCode bool) {
|
|
validCode = true
|
|
id, ok := co.codesToIndices[langCode]
|
|
if !ok {
|
|
// TODO: Tell the caller that the code's invalid
|
|
id = 0 // Unknown
|
|
validCode = false
|
|
}
|
|
|
|
// TODO: Test this check
|
|
c.DebugDetail("buckets ", id, ": ", co.buckets[id])
|
|
if len(co.buckets) <= id || id < 0 {
|
|
return validCode
|
|
}
|
|
atomic.AddInt64(&co.buckets[id], 1)
|
|
|
|
return validCode
|
|
}
|
|
|
|
func (co *DefaultLangViewCounter) Bump2(id int) {
|
|
// TODO: Test this check
|
|
c.DebugDetail("bucket ", id, ": ", co.buckets[id])
|
|
if len(co.buckets) <= id || id < 0 {
|
|
return
|
|
}
|
|
atomic.AddInt64(&co.buckets[id], 1)
|
|
}
|