gosora/common/counters/langs.go
Azareal 01a692ab5b Added the word filter store and moved the word filter routes into the route package.
Added tests for the word filter store.
Added qgen.NewAcc() to reduce the amount of boilerplate needed for creating an accumulator.
Exposed the RecordError method on the accumulator.
Added an Add method to PluginList and removed AddPlugin() in favour of that.

More panel buttons on Nox should be styled now.
Added the panel_update_button_text phrase for future use.

More errors might be caught in the thumbnailer now.
Removed ls from .travis.yml, it was there for debugging Code Climate.
2018-08-04 21:46:36 +10:00

168 lines
2.8 KiB
Go

package counters
import "database/sql"
import ".."
import "../../query_gen/lib"
var LangViewCounter *DefaultLangViewCounter
var langCodes = []string{
"unknown",
"none",
"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",
"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 []*RWMutexCounterBucket //[OSID]count
codesToIndices map[string]int
insert *sql.Stmt
}
func NewDefaultLangViewCounter() (*DefaultLangViewCounter, error) {
acc := qgen.NewAcc()
var langBuckets = make([]*RWMutexCounterBucket, len(langCodes))
for bucketID, _ := range langBuckets {
langBuckets[bucketID] = &RWMutexCounterBucket{counter: 0}
}
var codesToIndices = make(map[string]int)
for index, code := range langCodes {
codesToIndices[code] = index
}
counter := &DefaultLangViewCounter{
buckets: langBuckets,
codesToIndices: codesToIndices,
insert: acc.Insert("viewchunks_langs").Columns("count, createdAt, lang").Fields("?,UTC_TIMESTAMP(),?").Prepare(),
}
common.AddScheduledFifteenMinuteTask(counter.Tick)
//common.AddScheduledSecondTask(counter.Tick)
common.AddShutdownTask(counter.Tick)
return counter, acc.FirstError()
}
func (counter *DefaultLangViewCounter) Tick() error {
for id, bucket := range counter.buckets {
var count int
bucket.RLock()
count = bucket.counter
bucket.counter = 0 // TODO: Add a SetZero method to reduce the amount of duplicate code between the OS and agent counters?
bucket.RUnlock()
err := counter.insertChunk(count, id) // TODO: Bulk insert for speed?
if err != nil {
return err
}
}
return nil
}
func (counter *DefaultLangViewCounter) insertChunk(count int, id int) error {
if count == 0 {
return nil
}
var langCode = langCodes[id]
common.DebugLogf("Inserting a viewchunk with a count of %d for lang %s (%d)", count, langCode, id)
_, err := counter.insert.Exec(count, langCode)
return err
}
func (counter *DefaultLangViewCounter) Bump(langCode string) {
id, ok := counter.codesToIndices[langCode]
if !ok {
// TODO: Tell the caller that the code's invalid
id = 0 // Unknown
}
// TODO: Test this check
common.DebugDetail("counter.buckets[", id, "]: ", counter.buckets[id])
if len(counter.buckets) <= id || id < 0 {
return
}
counter.buckets[id].Lock()
counter.buckets[id].counter++
counter.buckets[id].Unlock()
}