diff options
| author | William Hergès <william@herges.fr> | 2026-01-17 19:57:28 +0100 |
|---|---|---|
| committer | William Hergès <william@herges.fr> | 2026-01-17 19:57:28 +0100 |
| commit | ec5cfa632eeb607351f67bad6686ec872291bd61 (patch) | |
| tree | c53b9bf7e14c44b49a17f088737b35eb5ad0b64e | |
| parent | c9129c2e7edcf6e588cac674dfdb240f1714083d (diff) | |
perf(command): top now partially uses state
| -rw-r--r-- | commands/top.go | 93 | ||||
| -rw-r--r-- | exp/functions.go | 2 | ||||
| -rw-r--r-- | main.go | 6 | ||||
| -rw-r--r-- | user/state.go | 7 | ||||
| -rw-r--r-- | user/xp.go | 16 |
5 files changed, 71 insertions, 53 deletions
diff --git a/commands/top.go b/commands/top.go index bd92a28..fa12a66 100644 --- a/commands/top.go +++ b/commands/top.go @@ -1,6 +1,7 @@ package commands import ( + "context" "fmt" "sync" @@ -13,62 +14,64 @@ import ( "github.com/nyttikord/gokord/event" ) -func Top(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { - err := resp.IsDeferred().Send() - if err != nil { - s.Logger().Error("sending deferred", "error", err) - return - } - embeds := make([]*channel.MessageEmbed, 3) - wg := sync.WaitGroup{} - - fn := func(str string, n uint, d int, id int) { - defer wg.Done() - tops, err := user.GetBestXP(s.Logger(), i.GuildID, n, d) +func Top(ctx context.Context) func(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { + return func(s bot.Session, i *event.InteractionCreate, _ cmd.OptionMap, resp *cmd.ResponseBuilder) { + err := resp.IsDeferred().Send() if err != nil { - s.Logger().Error("fetching best xp", "error", err, "n", n, "d", d, "id", id, "guild", i.GuildID) + s.Logger().Error("sending deferred", "error", err) + return + } + embeds := make([]*channel.MessageEmbed, 3) + wg := sync.WaitGroup{} + + fn := func(str string, n uint, d int, id int) { + defer wg.Done() + tops, err := user.GetBestXP(ctx, s.Logger(), i.GuildID, n, d) + if err != nil { + s.Logger().Error("fetching best xp", "error", err, "n", n, "d", d, "id", id, "guild", i.GuildID) + embeds[id] = &channel.MessageEmbed{ + Title: str, + Description: "Erreur : impossible de récupérer la liste", + Color: 0x831010, + } + return + } embeds[id] = &channel.MessageEmbed{ Title: str, - Description: "Erreur : impossible de récupérer la liste", - Color: 0x831010, + Description: genTopsMessage(tops), + Color: 0x10E6AD, } - return - } - embeds[id] = &channel.MessageEmbed{ - Title: str, - Description: genTopsMessage(tops), - Color: 0x10E6AD, } - } - cfg := config.GetGuildConfig(i.GuildID) - if cfg.DaysXPRemains > 30 { - wg.Add(1) - go fn(fmt.Sprintf("Top %d jours", cfg.DaysXPRemains), 10, -1, 0) - } - wg.Add(2) - go fn("Top 30 jours", 5, 30, 1) - go fn("Top 7 jours", 5, 7, 2) - go func() { - wg.Wait() + cfg := config.GetGuildConfig(i.GuildID) if cfg.DaysXPRemains > 30 { - resp.AddEmbed(embeds[0]). - AddEmbed(embeds[1]). - AddEmbed(embeds[2]) - } else { - resp.AddEmbed(embeds[1]). - AddEmbed(embeds[2]) - } - err = resp.Send() - if err != nil { - s.Logger().Error("sending response top", "error", err) + wg.Add(1) + go fn(fmt.Sprintf("Top %d jours", cfg.DaysXPRemains), 10, -1, 0) } - }() + wg.Add(2) + go fn("Top 30 jours", 5, 30, 1) + go fn("Top 7 jours", 5, 7, 2) + go func() { + wg.Wait() + if cfg.DaysXPRemains > 30 { + resp.AddEmbed(embeds[0]). + AddEmbed(embeds[1]). + AddEmbed(embeds[2]) + } else { + resp.AddEmbed(embeds[1]). + AddEmbed(embeds[2]) + } + err = resp.Send() + if err != nil { + s.Logger().Error("sending response top", "error", err) + } + }() + } } -func genTopsMessage(tops []user.CopaingAccess) string { +func genTopsMessage(tops []user.CopaingCached) string { msg := "" for i, c := range tops { - msg += fmt.Sprintf("%d. **<@%s>** - niveau %d", i+1, c.Copaing().DiscordID, exp.Level(c.GetXP())) + msg += fmt.Sprintf("%d. **<@%s>** - niveau %d", i+1, c.DiscordID, exp.Level(c.XPs)) if i != len(tops)-1 { msg += "\n" } diff --git a/exp/functions.go b/exp/functions.go index 681c135..1b2fe89 100644 --- a/exp/functions.go +++ b/exp/functions.go @@ -11,7 +11,7 @@ import ( "github.com/anhgelus/gokord" ) -const DebugFactor = 30 +const DebugFactor = 5 func MessageXP(length uint, diversity uint) uint { return uint(math.Floor( @@ -99,7 +99,7 @@ func main() { SetHandler(commands.ConfigCommand) topCmd := cmd.New("top", "Copaings les plus actifs"). - SetHandler(commands.Top) + SetHandler(commands.Top(ctx)) resetCmd := cmd.New("reset", "Reset l'xp"). SetHandler(commands.Reset). @@ -293,4 +293,8 @@ func main() { if stopPeriodicReducer != nil { stopPeriodicReducer <- true } + + if stopPeriodicSaver != nil { + stopPeriodicSaver <- true + } } diff --git a/user/state.go b/user/state.go index 540d496..b977fb6 100644 --- a/user/state.go +++ b/user/state.go @@ -41,6 +41,7 @@ func (cc *CopaingCached) Sync(ctx context.Context) error { synced := FromCopaing(cc.copaing()) synced.XPs += cc.XPToAdd synced.XPToAdd = cc.XPToAdd + synced.lastSync = time.Now() err := synced.Save(ctx) if err != nil { return err @@ -144,12 +145,12 @@ func (s *State) Copaing(guildID, copaingID string) (*CopaingCached, error) { s.mu.RLock() defer s.mu.RUnlock() - c, err := s.storage.Get(KeyCopaingCachedRaw(guildID, copaingID)) + raw, err := s.storage.Get(KeyCopaingCachedRaw(guildID, copaingID)) if err != nil { return nil, err } - mC := c.(CopaingCached) - return &mC, nil + c := raw.(CopaingCached) + return &c, nil } func (s *State) Copaings(guild string) []CopaingCached { @@ -78,10 +78,11 @@ func (c *Copaing) GetXPForDays(logger *slog.Logger, n uint) (uint, error) { // GetBestXP returns n Copaing with the best XP within d days (d <= cfg.DaysXPRemain; d < 0 <=> d = cfg.DaysXPRemain) // // This function is slow -func GetBestXP(logger *slog.Logger, guildId string, n uint, d int) ([]CopaingAccess, error) { +func GetBestXP(ctx context.Context, logger *slog.Logger, guildId string, n uint, d int) ([]CopaingCached, error) { if d < 0 { cfg := config.GetGuildConfig(guildId) d = int(cfg.DaysXPRemains) + return getBestXPFull(ctx, guildId, n), nil } rows, err := gokord.DB.Model(&Copaing{}).Where("guild_id = ?", guildId).Rows() if err != nil { @@ -112,9 +113,18 @@ func GetBestXP(logger *slog.Logger, guildId string, n uint, d int) ([]CopaingAcc return int(b.Cxp) - int(a.Cxp) }) m := min(len(l), int(n)) - cs := make([]CopaingAccess, m) + cs := make([]CopaingCached, m) for i, c := range l[:m] { - cs[i] = c + cs[i] = CopaingCached{DiscordID: c.copaing.DiscordID, XPs: c.Cxp} } return cs, nil } + +func getBestXPFull(ctx context.Context, guildId string, n uint) []CopaingCached { + ccs := GetState(ctx).Copaings(guildId) + slices.SortFunc(ccs, func(a, b CopaingCached) int { + return int(b.XPs) - int(a.XPs) + }) + m := min(len(ccs), int(n)) + return ccs[:m] +} |
