From 48ca185105988aba0626850bf133ba364edd835e Mon Sep 17 00:00:00 2001 From: Anhgelus Morhtuuzh Date: Mon, 15 Apr 2024 11:52:21 +0200 Subject: [PATCH] perf(redis): use the same client in all xp goroutines --- main.go | 2 ++ xp/events.go | 27 +++++++++++++-------------- xp/member.go | 23 +++++++++++++++++++++++ 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/main.go b/main.go index bbe995e..caede84 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,8 @@ func main() { AfterInit: afterInit, } bot.Start() + + xp.CloseRedisClient() } func afterInit(dg *discordgo.Session) { diff --git a/xp/events.go b/xp/events.go index cf991e6..f6b9bc5 100644 --- a/xp/events.go +++ b/xp/events.go @@ -46,25 +46,21 @@ func OnVoiceUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { if e.Member.User.Bot { return } - r, err := gokord.BaseCfg.Redis.Get() + client, err := getRedisClient() if err != nil { utils.SendAlert("xp/events.go - Getting redis client", err.Error()) return } if e.BeforeUpdate == nil { - onConnection(s, e, r) + onConnection(s, e, client) } else { - onDisconnect(s, e, r) - } - err = r.Close() - if err != nil { - utils.SendAlert("xp/events.go - Closing redis client", err.Error()) + onDisconnect(s, e, client) } } -func onConnection(_ *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis.Client) { +func onConnection(_ *discordgo.Session, e *discordgo.VoiceStateUpdate, client *redis.Client) { u := gokord.UserBase{DiscordID: e.UserID, GuildID: e.GuildID} - err := r.Set( + err := client.Set( context.Background(), fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince), strconv.FormatInt(time.Now().Unix(), 10), @@ -75,11 +71,12 @@ func onConnection(_ *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis. } } -func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis.Client) { +func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate, client *redis.Client) { + now := time.Now().Unix() u := gokord.UserBase{DiscordID: e.UserID, GuildID: e.GuildID} key := fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince) - res := r.Get(context.Background(), key) - now := time.Now().Unix() + res := client.Get(context.Background(), key) + // check validity of user (1) if errors.Is(res.Err(), redis.Nil) { utils.SendWarn(fmt.Sprintf( "User %s diconnect from a vocal but does not have a connected_since", @@ -89,7 +86,7 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis. } if res.Err() != nil { utils.SendAlert("xp/events.go - Getting connected_since", res.Err().Error()) - err := r.Set(context.Background(), key, strconv.Itoa(NotConnected), 0).Err() + err := client.Set(context.Background(), key, strconv.Itoa(NotConnected), 0).Err() if err != nil { utils.SendAlert("xp/events.go - Set connected_since to not connected after get err", err.Error()) } @@ -100,6 +97,7 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis. utils.SendAlert("xp/events.go - Converting result to int64", err.Error()) return } + // check validity of user (2) if con == NotConnected { utils.SendWarn(fmt.Sprintf( "User %s diconnect from a vocal but was registered as not connected", @@ -107,10 +105,11 @@ func onDisconnect(s *discordgo.Session, e *discordgo.VoiceStateUpdate, r *redis. )) return } - err = r.Set(context.Background(), key, strconv.Itoa(NotConnected), 0).Err() + err = client.Set(context.Background(), key, strconv.Itoa(NotConnected), 0).Err() if err != nil { utils.SendAlert("xp/events.go - Set connected_since to not connected", err.Error()) } + // add xp timeInVocal := now - con if timeInVocal < 0 { utils.SendAlert("xp/events.go - Calculating time spent in vocal", "the time is negative") diff --git a/xp/member.go b/xp/member.go index e3714fa..578e533 100644 --- a/xp/member.go +++ b/xp/member.go @@ -2,7 +2,9 @@ package xp import ( "github.com/anhgelus/gokord" + "github.com/anhgelus/gokord/utils" "github.com/bwmarrin/discordgo" + "github.com/redis/go-redis/v9" "gorm.io/gorm" ) @@ -13,6 +15,8 @@ type Copaing struct { GuildID string } +var r *redis.Client + func (c *Copaing) Load() *Copaing { gokord.DB.Where("discord_id = ? and guild_id = ?", c.DiscordID, c.GuildID).FirstOrCreate(c) return c @@ -32,3 +36,22 @@ func (c *Copaing) AddXP(s *discordgo.Session, xp uint, fn func(uint, uint)) { onNewLevel(s, newLevel) } } + +func getRedisClient() (*redis.Client, error) { + if r == nil { + var err error + r, err = gokord.BaseCfg.Redis.Get() + return r, err + } + return r, nil +} + +func CloseRedisClient() { + if r == nil { + return + } + err := r.Close() + if err != nil { + utils.SendAlert("xp/member.go - Closing redis client", err.Error()) + } +}