aboutsummaryrefslogtreecommitdiff
path: root/user/level.go
diff options
context:
space:
mode:
authorAnhgelus Morhtuuzh <william@herges.fr>2026-01-17 20:52:13 +0000
committerAnhgelus Morhtuuzh <william@herges.fr>2026-01-17 20:52:13 +0000
commita3543d79561a3754540b921c54c3c177016c2397 (patch)
tree318b29652c4f59a7f6a16ff7a566b1a9935d069d /user/level.go
parent05ec1c26fe884097efe8fe1490916c518028e597 (diff)
parentc661541e45dddd6a082af66fcf7df7ba7dfdc6a6 (diff)
Merge pull request '[Perf] Member state' (#5) from perf/member-state into main
Reviewed-on: https://git.anhgelus.world/anhgelus/les-copaings-bot/pulls/5
Diffstat (limited to 'user/level.go')
-rw-r--r--user/level.go95
1 files changed, 46 insertions, 49 deletions
diff --git a/user/level.go b/user/level.go
index e7b96af..92c10ab 100644
--- a/user/level.go
+++ b/user/level.go
@@ -1,6 +1,7 @@
package user
import (
+ "context"
"slices"
"sync"
"time"
@@ -45,7 +46,7 @@ func onNewLevel(s bot.Session, m *user.Member, level uint) {
}
}
-func (c *Copaing) OnNewLevel(s *discordgo.Session, level uint) {
+func (c *CopaingCached) onNewLevel(s *discordgo.Session, level uint) {
m, err := s.GuildAPI().Member(c.GuildID, c.DiscordID)
if err != nil {
s.Logger().Error("getting member for new level", "error", err, "user", c.DiscordID, "guild", c.GuildID)
@@ -54,65 +55,61 @@ func (c *Copaing) OnNewLevel(s *discordgo.Session, level uint) {
onNewLevel(s, m, level)
}
-func PeriodicReducer(s *discordgo.Session) {
- wg := &sync.WaitGroup{}
- var cs []*Copaing
- if err := gokord.DB.Find(&cs).Error; err != nil {
- s.Logger().Error("fetching all copaings", "error", err)
- return
- }
- cxps := make([]*cXP, len(cs))
- for i, c := range cs {
- if i%25 == 24 {
- wg.Wait() // prevents spamming the DB
- }
- wg.Add(1)
- go func() {
- defer wg.Done()
- xp, err := c.GetXP(s.Logger())
- if err != nil {
- s.Logger().Error("getting xp", "error", err, "copaing", c.ID, "guild", c.GuildID)
- xp = 0
- }
- cxps[i] = &cXP{
- Cxp: xp,
- Copaing: c,
- }
- }()
- }
- wg.Wait()
- i := 0
+func PeriodicReducer(ctx context.Context, s *discordgo.Session) {
+ PeriodicSaver(ctx, s)
+
+ s.Logger().Debug("periodic reducer")
+
+ state := GetState(ctx)
+
+ n := 0
+ var wg sync.WaitGroup
for _, g := range s.GuildAPI().State.Guilds() {
- i++
- wg.Add(1)
- go func() {
- defer wg.Done()
- cfg := config.GetGuildConfig(g)
- res := gokord.DB.
- Model(&CopaingXP{}).
- Where("guild_id = ? and created_at < ?", g, exp.TimeStampNDaysBefore(cfg.DaysXPRemains)).
- Delete(&CopaingXP{})
- if res.Error != nil {
- s.Logger().Error("removing old xp", "error", res.Error, "guild", g)
- }
- s.Logger().Debug("guild cleaned", "guild", g, "rows affected", res.RowsAffected)
- }()
+ n++
+ cfg := config.GetGuildConfig(g)
+ res := gokord.DB.
+ Model(&CopaingXP{}).
+ Where("guild_id = ? and created_at < ?", g, exp.TimeStampNDaysBefore(cfg.DaysXPRemains)).
+ Delete(&CopaingXP{})
+ if res.Error != nil {
+ s.Logger().Error("removing old xp", "error", res.Error, "guild", g)
+ continue
+ }
+ s.Logger().Debug("guild cleaned", "guild", g, "rows affected", res.RowsAffected)
+
+ wg.Go(func() {
+ syncCopaings(ctx, s, state.Copaings(g))
+ })
}
+
wg.Wait()
- for i, c := range cxps {
+
+ s.Logger().Debug("periodic reduce finished", "guilds affected", n)
+}
+
+func syncCopaings(ctx context.Context, s *discordgo.Session, ccs []CopaingCached) {
+ for i, cc := range ccs {
if i%50 == 49 {
s.Logger().Debug("sleeping...")
time.Sleep(15 * time.Second) // prevents spamming the API
}
- oldXp := c.GetXP()
- xp, err := c.ToCopaing().GetXP(s.Logger())
+ oldXp := cc.XP
+ err := cc.Sync(ctx)
if err != nil {
- s.Logger().Error("getting xp of copaing", "error", err, "copaing", c.ID, "guild", c.GuildID)
+ s.Logger().Error("syncing copaing", "error", err, "copaing", cc.ID, "guild", cc.GuildID)
continue
}
+ xp := cc.XP
if exp.Level(oldXp) != exp.Level(xp) {
- c.OnNewLevel(s, exp.Level(xp))
+ cc.onNewLevel(s, exp.Level(xp))
}
}
- s.Logger().Debug("periodic reduce finished", "guilds affected", i)
+}
+
+func PeriodicSaver(ctx context.Context, s bot.Session) {
+ s.Logger().Debug("saving state in DB")
+ err := saveStateInDB(ctx)
+ if err != nil {
+ panic(err)
+ }
}