106 lines
2.3 KiB
Go
106 lines
2.3 KiB
Go
package activity
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
"time"
|
|
|
|
"gitlab.com/whom/bingobot/internal/config"
|
|
"gitlab.com/whom/bingobot/internal/state"
|
|
"gitlab.com/whom/bingobot/internal/logging"
|
|
)
|
|
|
|
/* Activity module
|
|
* This module sits and processes incoming
|
|
*/
|
|
|
|
const (
|
|
ActivityModuleStartFail = "failed to start activity module"
|
|
)
|
|
|
|
var currentUserActivity map[string][]state.UserActiveEvent
|
|
var userActivityLock sync.RWMutex
|
|
|
|
func Start() error {
|
|
ch, err := state.UserActive.Subscribe()
|
|
if err != nil {
|
|
return errors.Join(
|
|
errors.New(ActivityModuleStartFail),
|
|
err,
|
|
)
|
|
}
|
|
|
|
// process incoming events loop
|
|
go func() {
|
|
for {
|
|
ev := <- ch
|
|
emap := ev.Data()
|
|
user := emap[state.UserEventUserKey]
|
|
etime := ev.Time()
|
|
delta := time.Since(etime).Hours() / float64(24)
|
|
|
|
if delta <= float64(config.Get().UserEventLifespanDays) {
|
|
new := []state.UserActiveEvent{ev.(state.UserActiveEvent)}
|
|
userActivityLock.Lock()
|
|
current, found := currentUserActivity[user]
|
|
if found {
|
|
new = append(new, current...)
|
|
}
|
|
userActivityLock.Unlock()
|
|
} else {
|
|
logging.Warn("recieved expired useractive event")
|
|
}
|
|
}
|
|
}()
|
|
|
|
// process expired events loop
|
|
go func() {
|
|
for {
|
|
delta := time.Hour * 24
|
|
delta *= time.Duration(config.Get().UserEventLifespanDays)
|
|
tcur := time.Now().Add(delta)
|
|
|
|
// get next soonest expiration
|
|
userActivityLock.RLock()
|
|
for _, evs := range currentUserActivity {
|
|
for _, ev := range evs {
|
|
hrs := time.Duration(24 * config.Get().UserEventLifespanDays)
|
|
t := ev.Time().Add(time.Hour * hrs)
|
|
if t.Before(tcur) {
|
|
tcur = t
|
|
}
|
|
}
|
|
}
|
|
userActivityLock.RUnlock()
|
|
time.Sleep(tcur.Sub(time.Now()))
|
|
|
|
userActivityLock.Lock()
|
|
for k, v := range currentUserActivity {
|
|
new := []state.UserActiveEvent{}
|
|
for _, ev := range v {
|
|
if !ev.Disposable() {
|
|
new = append(new, ev)
|
|
}
|
|
}
|
|
currentUserActivity[k] = new
|
|
}
|
|
userActivityLock.Unlock()
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetActivitySnapshot() map[string][]state.UserActiveEvent {
|
|
userActivityLock.RLock()
|
|
defer userActivityLock.RUnlock()
|
|
|
|
snapshot := make(map[string][]state.UserActiveEvent)
|
|
for k, v := range currentUserActivity {
|
|
newSl := make([]state.UserActiveEvent, len(v))
|
|
copy(newSl, v)
|
|
snapshot[k] = newSl
|
|
}
|
|
|
|
return snapshot
|
|
}
|