perf(redis): use the same client in all xp goroutines

This commit is contained in:
Anhgelus Morhtuuzh 2024-04-15 11:52:21 +02:00
parent dcc260c4b0
commit 48ca185105
No known key found for this signature in database
GPG key ID: CF4550297832A29F
3 changed files with 38 additions and 14 deletions

View file

@ -51,6 +51,8 @@ func main() {
AfterInit: afterInit, AfterInit: afterInit,
} }
bot.Start() bot.Start()
xp.CloseRedisClient()
} }
func afterInit(dg *discordgo.Session) { func afterInit(dg *discordgo.Session) {

View file

@ -46,25 +46,21 @@ func OnVoiceUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) {
if e.Member.User.Bot { if e.Member.User.Bot {
return return
} }
r, err := gokord.BaseCfg.Redis.Get() client, err := getRedisClient()
if err != nil { if err != nil {
utils.SendAlert("xp/events.go - Getting redis client", err.Error()) utils.SendAlert("xp/events.go - Getting redis client", err.Error())
return return
} }
if e.BeforeUpdate == nil { if e.BeforeUpdate == nil {
onConnection(s, e, r) onConnection(s, e, client)
} else { } else {
onDisconnect(s, e, r) onDisconnect(s, e, client)
}
err = r.Close()
if err != nil {
utils.SendAlert("xp/events.go - Closing redis client", err.Error())
} }
} }
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} u := gokord.UserBase{DiscordID: e.UserID, GuildID: e.GuildID}
err := r.Set( err := client.Set(
context.Background(), context.Background(),
fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince), fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince),
strconv.FormatInt(time.Now().Unix(), 10), 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} u := gokord.UserBase{DiscordID: e.UserID, GuildID: e.GuildID}
key := fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince) key := fmt.Sprintf("%s:%s", u.GenKey(), ConnectedSince)
res := r.Get(context.Background(), key) res := client.Get(context.Background(), key)
now := time.Now().Unix() // check validity of user (1)
if errors.Is(res.Err(), redis.Nil) { if errors.Is(res.Err(), redis.Nil) {
utils.SendWarn(fmt.Sprintf( utils.SendWarn(fmt.Sprintf(
"User %s diconnect from a vocal but does not have a connected_since", "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 { if res.Err() != nil {
utils.SendAlert("xp/events.go - Getting connected_since", res.Err().Error()) 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 { if err != nil {
utils.SendAlert("xp/events.go - Set connected_since to not connected after get err", err.Error()) 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()) utils.SendAlert("xp/events.go - Converting result to int64", err.Error())
return return
} }
// check validity of user (2)
if con == NotConnected { if con == NotConnected {
utils.SendWarn(fmt.Sprintf( utils.SendWarn(fmt.Sprintf(
"User %s diconnect from a vocal but was registered as not connected", "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 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 { if err != nil {
utils.SendAlert("xp/events.go - Set connected_since to not connected", err.Error()) utils.SendAlert("xp/events.go - Set connected_since to not connected", err.Error())
} }
// add xp
timeInVocal := now - con timeInVocal := now - con
if timeInVocal < 0 { if timeInVocal < 0 {
utils.SendAlert("xp/events.go - Calculating time spent in vocal", "the time is negative") utils.SendAlert("xp/events.go - Calculating time spent in vocal", "the time is negative")

View file

@ -2,7 +2,9 @@ package xp
import ( import (
"github.com/anhgelus/gokord" "github.com/anhgelus/gokord"
"github.com/anhgelus/gokord/utils"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/redis/go-redis/v9"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -13,6 +15,8 @@ type Copaing struct {
GuildID string GuildID string
} }
var r *redis.Client
func (c *Copaing) Load() *Copaing { func (c *Copaing) Load() *Copaing {
gokord.DB.Where("discord_id = ? and guild_id = ?", c.DiscordID, c.GuildID).FirstOrCreate(c) gokord.DB.Where("discord_id = ? and guild_id = ?", c.DiscordID, c.GuildID).FirstOrCreate(c)
return c return c
@ -32,3 +36,22 @@ func (c *Copaing) AddXP(s *discordgo.Session, xp uint, fn func(uint, uint)) {
onNewLevel(s, newLevel) 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())
}
}