From fe4e0634875f59f51ca55e862009af35d4ab1ced Mon Sep 17 00:00:00 2001 From: Arkdady Skvoretsky Date: Wed, 24 Jul 2024 01:30:39 +0300 Subject: [PATCH] Memory optimizations --- cmd/migrator/main.go | 2 +- cmd/service/main.go | 31 ++++++++---------- internal/db/config.go | 4 +-- internal/db/migrator.go | 12 +++---- internal/db/probe.go | 6 ++-- internal/db/quotes.go | 8 ++--- internal/discord/config.go | 38 +++++++++++----------- internal/discord/probe.go | 14 ++++---- internal/discord/types.go | 2 +- internal/handlers/cast/handler.go | 47 ++++++++++++--------------- internal/handlers/lock/handler.go | 32 +++++++++--------- internal/handlers/quote/addQuote.go | 5 ++- internal/handlers/quote/handler.go | 41 ++++++++++++----------- internal/handlers/quote/listQuotes.go | 23 +++++++------ internal/handlers/roll/handler.go | 26 +++++++-------- internal/handlers/unlock/handler.go | 40 +++++++++++------------ internal/pkg/config/config.go | 6 ++-- internal/pkg/dbUtils/txWrapper.go | 4 +-- internal/pkg/discordUtils/utils.go | 45 +++++++++++++++++-------- internal/pkg/utils/utils.go | 2 +- 20 files changed, 196 insertions(+), 192 deletions(-) diff --git a/cmd/migrator/main.go b/cmd/migrator/main.go index 9fc667f..9e5f4b6 100644 --- a/cmd/migrator/main.go +++ b/cmd/migrator/main.go @@ -24,7 +24,7 @@ func main() { dbLogger := logger.WithGroup("db") // db - dbConn := db.Connect(cfg.DB) + dbConn := db.Connect(cfg.DB.ConnectionString) defer dbConn.Close() txWrapper := dbUtils.NewTxWrapper(dbLogger, dbConn) dbMigrator := db.NewMigrator(dbLogger, dbConn, txWrapper) diff --git a/cmd/service/main.go b/cmd/service/main.go index d7baddc..184b536 100644 --- a/cmd/service/main.go +++ b/cmd/service/main.go @@ -41,46 +41,43 @@ func main() { hcLogger := logger.WithGroup("healthcheck") // db - dbConn := db.Connect(cfg.DB) + dbConn := db.Connect(cfg.DB.ConnectionString) defer dbConn.Close() dbProbe := db.NewProbe(dbConn) txWrapper := dbUtils.NewTxWrapper(dbLogger, dbConn) - // discord - discordConn := discord.Connect(cfg.Discord.Token) - defer discordConn.Close() - discordProbe := discord.NewProbe(discordConn) - - // repos quotesRepo := db.NewQuotesRepo(dbLogger, dbConn, txWrapper) - // handlers - cmds := map[string]*discord.Command{ + // discord + discordSession := discord.Connect(cfg.Discord.Token) + defer discordSession.Close() + + commands := map[string]*discord.Command{ discord.QuoteName: { Description: discord.Quote, - Handler: quote.New(ctx, cmdLogger, quotesRepo), + Handler: quote.New(ctx, cmdLogger, discordSession, quotesRepo), }, discord.CastName: { Description: discord.Cast, - Handler: cast.New(ctx, cmdLogger), + Handler: cast.New(ctx, cmdLogger, discordSession), }, discord.LockName: { Description: discord.Lock, - Handler: lock.New(ctx, cmdLogger), + Handler: lock.New(ctx, cmdLogger, discordSession), }, discord.UnlockName: { Description: discord.Unlock, - Handler: unlock.New(ctx, cmdLogger), + Handler: unlock.New(ctx, cmdLogger, discordSession), }, discord.RollName: { Description: discord.Roll, - Handler: roll.New(ctx, cmdLogger), + Handler: roll.New(ctx, cmdLogger, discordSession), }, } + discord.RegisterCommands(discordSession, commands, cfg.Discord.Guild) + defer discord.UnregisterCommands(discordSession, commands, cfg.Discord.Guild) - // handlers - discord.RegisterCommands(discordConn, cmds, cfg.Discord.Guild) - defer discord.UnregisterCommands(discordConn, cmds, cfg.Discord.Guild) + discordProbe := discord.NewProbe(discordSession) // healthcheck hc := healthcheck.New( diff --git a/internal/db/config.go b/internal/db/config.go index c9a9a9a..7e75e9c 100644 --- a/internal/db/config.go +++ b/internal/db/config.go @@ -11,8 +11,8 @@ type Config struct { ConnectionString string `conf:"connection_string"` } -func Connect(cfg Config) *sql.DB { - db, err := sql.Open("postgres", cfg.ConnectionString) +func Connect(cs string) *sql.DB { + db, err := sql.Open("postgres", cs) if err != nil { log.Fatalln("failed to open database connection:", err) } diff --git a/internal/db/migrator.go b/internal/db/migrator.go index 1cf953d..4abb586 100644 --- a/internal/db/migrator.go +++ b/internal/db/migrator.go @@ -20,15 +20,15 @@ func NewMigrator( log *slog.Logger, db *sql.DB, txWrapper dbUtils.TxWrapper, -) Migrator { - return Migrator{ +) *Migrator { + return &Migrator{ log: log.With("type", "migrator"), db: db, txWrapper: txWrapper, } } -func (m Migrator) Migrate() error { +func (m *Migrator) Migrate() error { err := m.createMigrationTable() if err != nil { m.log.Error( @@ -90,7 +90,7 @@ func (m Migrator) Migrate() error { return nil } -func (m Migrator) createMigrationTable() error { +func (m *Migrator) createMigrationTable() error { return m.txWrapper.Wrap( context.Background(), func(_ context.Context, tx *sql.Tx) error { _, err := tx.Exec( @@ -105,7 +105,7 @@ func (m Migrator) createMigrationTable() error { ) } -func (m Migrator) registerAppliedMigration(migration string) error { +func (m *Migrator) registerAppliedMigration(migration string) error { return m.txWrapper.Wrap( context.Background(), func(_ context.Context, tx *sql.Tx) error { _, err := tx.Exec( @@ -117,7 +117,7 @@ func (m Migrator) registerAppliedMigration(migration string) error { ) } -func (m Migrator) checkMigration(migration string) (bool, error) { +func (m *Migrator) checkMigration(migration string) (bool, error) { rows, err := m.db.Query( `select exists(select 1 from "migrations" where "name" = $1)`, migration, diff --git a/internal/db/probe.go b/internal/db/probe.go index cedca22..8587a1f 100644 --- a/internal/db/probe.go +++ b/internal/db/probe.go @@ -9,12 +9,12 @@ type Probe struct { db *sql.DB } -func NewProbe(db *sql.DB) Probe { - return Probe{ +func NewProbe(db *sql.DB) *Probe { + return &Probe{ db: db, } } -func (p Probe) Check(ctx context.Context) error { +func (p *Probe) Check(ctx context.Context) error { return p.db.PingContext(ctx) } diff --git a/internal/db/quotes.go b/internal/db/quotes.go index 65b423c..27baea1 100644 --- a/internal/db/quotes.go +++ b/internal/db/quotes.go @@ -21,15 +21,15 @@ func NewQuotesRepo( log *slog.Logger, db *sql.DB, txWrapper dbUtils.TxWrapper, -) QuotesRepo { - return QuotesRepo{ +) *QuotesRepo { + return &QuotesRepo{ log: log.With("repo", "quotes"), db: db, txWrapper: txWrapper, } } -func (r QuotesRepo) GetUserQuotesOnGuild( +func (r *QuotesRepo) GetUserQuotesOnGuild( ctx context.Context, authorID types.ID, guildID types.ID, @@ -73,7 +73,7 @@ func (r QuotesRepo) GetUserQuotesOnGuild( return quotes, nil } -func (r QuotesRepo) AddUserQuoteOnGuild( +func (r *QuotesRepo) AddUserQuoteOnGuild( ctx context.Context, quote *models.Quote, ) error { diff --git a/internal/discord/config.go b/internal/discord/config.go index 1d97b77..fac7a16 100644 --- a/internal/discord/config.go +++ b/internal/discord/config.go @@ -20,33 +20,33 @@ func Connect(token string) *discordgo.Session { discordgo.Unmarshal = sonic.Unmarshal cs := fmt.Sprintf("Bot %s", token) - discord, err := discordgo.New(cs) + session, err := discordgo.New(cs) if err != nil { - log.Fatalln("failed to create discord client:", err) + log.Fatalln("failed to create Discord client:", err) } - discord.Identify.Intents = discordgo.IntentGuilds | + session.Identify.Intents = discordgo.IntentGuilds | discordgo.IntentGuildPresences | discordgo.IntentGuildMembers | discordgo.IntentGuildVoiceStates - err = discord.Open() + err = session.Open() if err != nil { log.Fatalln("failed to open Discord session:", err) } - return discord + return session } func RegisterCommands( - discord *discordgo.Session, - cmds map[string]*Command, + session *discordgo.Session, + commands map[string]*Command, guildID types.ID, ) { - appID := discord.State.Application.ID + appID := session.State.Application.ID - for name, cmd := range cmds { - createdCmd, err := discord.ApplicationCommandCreate( + for name, cmd := range commands { + createdCmd, err := session.ApplicationCommandCreate( appID, guildID.String(), cmd.Description, ) if err != nil { @@ -56,31 +56,31 @@ func RegisterCommands( cmd.Description = createdCmd } - discord.AddHandler( - func(s *discordgo.Session, i *discordgo.InteractionCreate) { + session.AddHandler( + func(_ *discordgo.Session, i *discordgo.InteractionCreate) { defer func() { if err := recover(); err != nil { log.Println("panic:", err) } }() - if cmd, ok := cmds[i.ApplicationCommandData().Name]; ok { - cmd.Handler.Handle(s, i) + if cmd, ok := commands[i.ApplicationCommandData().Name]; ok { + cmd.Handler.Handle(i) } }, ) } func UnregisterCommands( - discord *discordgo.Session, - cmds map[string]*Command, + session *discordgo.Session, + commands map[string]*Command, guildID types.ID, ) { - appID := discord.State.Application.ID + appID := session.State.Application.ID failedCmds := map[string]error{} - for name, cmd := range cmds { - err := discord.ApplicationCommandDelete( + for name, cmd := range commands { + err := session.ApplicationCommandDelete( appID, guildID.String(), cmd.Description.ID, ) if err != nil { diff --git a/internal/discord/probe.go b/internal/discord/probe.go index e550e6d..4ebe6d3 100644 --- a/internal/discord/probe.go +++ b/internal/discord/probe.go @@ -7,18 +7,18 @@ import ( ) type Probe struct { - discord *discordgo.Session + session *discordgo.Session } func NewProbe( - discord *discordgo.Session, -) Probe { - return Probe{ - discord: discord, + session *discordgo.Session, +) *Probe { + return &Probe{ + session: session, } } -func (p Probe) Check(_ context.Context) error { - _, err := p.discord.User("@me") +func (p *Probe) Check(_ context.Context) error { + _, err := p.session.User("@me") return err } diff --git a/internal/discord/types.go b/internal/discord/types.go index f0232b7..ea9a7e0 100644 --- a/internal/discord/types.go +++ b/internal/discord/types.go @@ -5,7 +5,7 @@ import ( ) type Handler interface { - Handle(s *discordgo.Session, i *discordgo.InteractionCreate) + Handle(i *discordgo.InteractionCreate) } type Command struct { diff --git a/internal/handlers/cast/handler.go b/internal/handlers/cast/handler.go index 4756ea1..637b6cb 100644 --- a/internal/handlers/cast/handler.go +++ b/internal/handlers/cast/handler.go @@ -14,36 +14,36 @@ import ( ) type Handler struct { - ctx context.Context - log *slog.Logger - utils discordUtils.Utils + ctx context.Context + log *slog.Logger + session *discordgo.Session + utils discordUtils.Utils } func New( ctx context.Context, log *slog.Logger, -) Handler { + session *discordgo.Session, +) *Handler { log = log.With("command", discord.CastName) - return Handler{ - ctx: ctx, - log: log, - utils: discordUtils.New(log), + return &Handler{ + ctx: ctx, + log: log, + session: session, + utils: discordUtils.New(ctx, log, session), } } -func (h Handler) Handle( - s *discordgo.Session, - i *discordgo.InteractionCreate, -) { - channelID, err := h.getChannelID(s, i) +func (h *Handler) Handle(i *discordgo.InteractionCreate) { + channelID, err := h.getChannelID(i) if err != nil && !errors.Is(err, discordgo.ErrStateNotFound) { h.log.Error("failed to get channel ID", "error", err) return } channelUsers, err := h.utils.GetVoiceChannelUsers( - s, types.ID(i.GuildID), types.ID(channelID), + types.ID(i.GuildID), types.ID(channelID), ) if err != nil { h.log.Error("failed to get channel users", "error", err) @@ -52,31 +52,26 @@ func (h Handler) Handle( if (len(channelUsers) == 1 && channelUsers[0].User.ID == i.Member.User.ID) || len(channelUsers) == 0 { - _ = h.utils.Respond(h.ctx, s, i, responses.CastNoUsers()) + _ = h.utils.Respond(i, responses.CastNoUsers()) + } else { + _ = h.utils.Respond(i, responses.CastUsers(i.Member, channelUsers)) } - - _ = h.utils.Respond( - h.ctx, s, i, responses.CastUsers(i.Member, channelUsers), - ) } -func (h Handler) getChannelID( - s *discordgo.Session, - i *discordgo.InteractionCreate, -) (string, error) { +func (h *Handler) getChannelID(i *discordgo.InteractionCreate) (string, error) { optionsMap := discordUtils.OptionsMap(i) if opt, ok := optionsMap[discord.CastOptionChannel]; ok { - return opt.ChannelValue(s).ID, nil + return opt.ChannelValue(h.session).ID, nil } - voiceState, err := s.State.VoiceState(i.GuildID, i.Member.User.ID) + voiceState, err := h.session.State.VoiceState(i.GuildID, i.Member.User.ID) switch { case err == nil: return voiceState.ChannelID, nil case errors.Is(err, discordgo.ErrStateNotFound): - _ = h.utils.Respond(h.ctx, s, i, responses.UserNotInVoiceChannel()) + _ = h.utils.Respond(i, responses.UserNotInVoiceChannel()) return "", err default: return "", errors.New("failed to get user voice state") diff --git a/internal/handlers/lock/handler.go b/internal/handlers/lock/handler.go index 72db391..bc987d8 100644 --- a/internal/handlers/lock/handler.go +++ b/internal/handlers/lock/handler.go @@ -12,29 +12,29 @@ import ( ) type Handler struct { - ctx context.Context - log *slog.Logger - utils discordUtils.Utils + ctx context.Context + log *slog.Logger + session *discordgo.Session + utils discordUtils.Utils } func New( ctx context.Context, log *slog.Logger, -) Handler { + session *discordgo.Session, +) *Handler { log = log.With("command", discord.LockName) - return Handler{ - ctx: ctx, - log: log, - utils: discordUtils.New(log), + return &Handler{ + ctx: ctx, + log: log, + session: session, + utils: discordUtils.New(ctx, log, session), } } -func (h Handler) Handle( - s *discordgo.Session, - i *discordgo.InteractionCreate, -) { - guild, err := s.State.Guild(i.GuildID) +func (h *Handler) Handle(i *discordgo.InteractionCreate) { + guild, err := h.session.State.Guild(i.GuildID) if err != nil { h.log.ErrorContext(h.ctx, "failed to get guild", "error", err) return @@ -51,7 +51,7 @@ func (h Handler) Handle( } if channelID == "" { - _ = h.utils.Respond(h.ctx, s, i, responses.UserNotInVoiceChannel()) + _ = h.utils.Respond(i, responses.UserNotInVoiceChannel()) return } @@ -60,7 +60,7 @@ func (h Handler) Handle( limit = int(opt.IntValue()) } - channel, err := s.ChannelEdit( + channel, err := h.session.ChannelEdit( channelID, &discordgo.ChannelEdit{ UserLimit: limit, }, @@ -70,5 +70,5 @@ func (h Handler) Handle( return } - _ = h.utils.Respond(h.ctx, s, i, responses.LockedChannel(channel, limit)) + _ = h.utils.Respond(i, responses.LockedChannel(channel, limit)) } diff --git a/internal/handlers/quote/addQuote.go b/internal/handlers/quote/addQuote.go index 506d5b8..80afa28 100644 --- a/internal/handlers/quote/addQuote.go +++ b/internal/handlers/quote/addQuote.go @@ -8,8 +8,7 @@ import ( "github.com/nijeti/cinema-keeper/internal/types" ) -func (h Handler) addQuote( - s *discordgo.Session, +func (h *Handler) addQuote( i *discordgo.InteractionCreate, author *discordgo.Member, text string, @@ -28,5 +27,5 @@ func (h Handler) addQuote( quote.Author = author quote.AddedBy = i.Interaction.Member - _ = h.utils.Respond(h.ctx, s, i, responses.QuoteAdded(quote)) + _ = h.utils.Respond(i, responses.QuoteAdded(quote)) } diff --git a/internal/handlers/quote/handler.go b/internal/handlers/quote/handler.go index 65deedc..ffc3bc7 100644 --- a/internal/handlers/quote/handler.go +++ b/internal/handlers/quote/handler.go @@ -11,51 +11,50 @@ import ( ) type Handler struct { - ctx context.Context - log *slog.Logger - utils discordUtils.Utils - db db + ctx context.Context + log *slog.Logger + session *discordgo.Session + db db + utils discordUtils.Utils } func New( ctx context.Context, log *slog.Logger, + session *discordgo.Session, db db, -) Handler { +) *Handler { log = log.With("command", discord.QuoteName) - return Handler{ - ctx: ctx, - log: log, - utils: discordUtils.New(log), - db: db, + return &Handler{ + ctx: ctx, + log: log, + session: session, + db: db, + utils: discordUtils.New(ctx, log, session), } } -func (h Handler) Handle( - s *discordgo.Session, - i *discordgo.InteractionCreate, -) { - author, text, err := h.getOptions(s, i) +func (h *Handler) Handle(i *discordgo.InteractionCreate) { + author, text, err := h.getOptions(i) if err != nil { h.log.ErrorContext(h.ctx, "failed to get options", "error", err) } if text == "" { - h.listQuotes(s, i, author) + h.listQuotes(i, author) } else { - h.addQuote(s, i, author, text) + h.addQuote(i, author, text) } } -func (h Handler) getOptions( - s *discordgo.Session, +func (h *Handler) getOptions( i *discordgo.InteractionCreate, ) (*discordgo.Member, string, error) { optionsMap := discordUtils.OptionsMap(i) - authorID := optionsMap[discord.QuoteOptionAuthor].UserValue(s).ID - author, err := s.State.Member(i.GuildID, authorID) + authorID := optionsMap[discord.QuoteOptionAuthor].UserValue(h.session).ID + author, err := h.session.State.Member(i.GuildID, authorID) if err != nil { return nil, "", err } diff --git a/internal/handlers/quote/listQuotes.go b/internal/handlers/quote/listQuotes.go index ed713f0..82502be 100644 --- a/internal/handlers/quote/listQuotes.go +++ b/internal/handlers/quote/listQuotes.go @@ -8,8 +8,7 @@ import ( "github.com/nijeti/cinema-keeper/internal/types" ) -func (h Handler) listQuotes( - s *discordgo.Session, +func (h *Handler) listQuotes( i *discordgo.InteractionCreate, author *discordgo.Member, ) { @@ -23,16 +22,16 @@ func (h Handler) listQuotes( } if len(quotes) == 0 { - _ = h.utils.Respond(h.ctx, s, i, responses.QuotesEmpty(author)) + _ = h.utils.Respond(i, responses.QuotesEmpty(author)) return } - err = h.enrichQuotes(s, i, quotes, author) + err = h.enrichQuotes(i, quotes, author) if err != nil { return } - err = h.utils.Respond(h.ctx, s, i, responses.QuotesHeader(author)) + err = h.utils.Respond(i, responses.QuotesHeader(author)) if err != nil { return } @@ -43,15 +42,14 @@ func (h Handler) listQuotes( limit = len(quotes) } - err = h.sendEmbeds(s, i, responses.Quotes(quotes[index:limit])) + err = h.sendEmbeds(i, responses.Quotes(quotes[index:limit])) if err != nil { return } } } -func (h Handler) enrichQuotes( - s *discordgo.Session, +func (h *Handler) enrichQuotes( i *discordgo.InteractionCreate, quotes []*models.Quote, author *discordgo.Member, @@ -59,7 +57,7 @@ func (h Handler) enrichQuotes( for _, q := range quotes { q.Author = author - addedBy, err := s.State.Member(i.GuildID, q.AddedByID.String()) + addedBy, err := h.session.State.Member(i.GuildID, q.AddedByID.String()) if err != nil { h.log.ErrorContext(h.ctx, "failed to get member", "error", err) return err @@ -69,12 +67,13 @@ func (h Handler) enrichQuotes( return nil } -func (h Handler) sendEmbeds( - s *discordgo.Session, +func (h *Handler) sendEmbeds( i *discordgo.InteractionCreate, embeds []*discordgo.MessageEmbed, ) error { - _, err := s.ChannelMessageSendEmbeds(i.Interaction.ChannelID, embeds) + _, err := h.session.ChannelMessageSendEmbeds( + i.Interaction.ChannelID, embeds, + ) if err != nil { h.log.ErrorContext(h.ctx, "failed to send embeds", "error", err) } diff --git a/internal/handlers/roll/handler.go b/internal/handlers/roll/handler.go index 9b16f88..3b303c0 100644 --- a/internal/handlers/roll/handler.go +++ b/internal/handlers/roll/handler.go @@ -13,28 +13,28 @@ import ( ) type Handler struct { - ctx context.Context - log *slog.Logger - utils discordUtils.Utils + ctx context.Context + log *slog.Logger + session *discordgo.Session + utils discordUtils.Utils } func New( ctx context.Context, log *slog.Logger, -) Handler { + session *discordgo.Session, +) *Handler { log = log.With("command", discord.RollName) - return Handler{ - ctx: ctx, - log: log, - utils: discordUtils.New(log), + return &Handler{ + ctx: ctx, + log: log, + session: session, + utils: discordUtils.New(ctx, log, session), } } -func (h Handler) Handle( - s *discordgo.Session, - i *discordgo.InteractionCreate, -) { +func (h *Handler) Handle(i *discordgo.InteractionCreate) { size := discord.RollOptionSizeDefault count := discord.RollOptionCountDefault @@ -62,5 +62,5 @@ func (h Handler) Handle( response = responses.RollMultiple(size, results) } - _ = h.utils.Respond(h.ctx, s, i, response) + _ = h.utils.Respond(i, response) } diff --git a/internal/handlers/unlock/handler.go b/internal/handlers/unlock/handler.go index 792bc4d..a097b9a 100644 --- a/internal/handlers/unlock/handler.go +++ b/internal/handlers/unlock/handler.go @@ -14,56 +14,54 @@ import ( ) type Handler struct { - ctx context.Context - log *slog.Logger - utils discordUtils.Utils + ctx context.Context + log *slog.Logger + session *discordgo.Session + utils discordUtils.Utils } func New( ctx context.Context, log *slog.Logger, -) Handler { + session *discordgo.Session, +) *Handler { log = log.With("command", discord.UnlockName) - return Handler{ - ctx: ctx, - log: log, - utils: discordUtils.New(log), + return &Handler{ + ctx: ctx, + log: log, + session: session, + utils: discordUtils.New(ctx, log, session), } } -func (h Handler) Handle( - s *discordgo.Session, - i *discordgo.InteractionCreate, -) { - voiceState, err := s.State.VoiceState(i.GuildID, i.Member.User.ID) +func (h *Handler) Handle(i *discordgo.InteractionCreate) { + voiceState, err := h.session.State.VoiceState(i.GuildID, i.Member.User.ID) if err != nil && !errors.Is(err, discordgo.ErrStateNotFound) { h.log.ErrorContext(h.ctx, "failed to get voice state", "error", err) return } if errors.Is(err, discordgo.ErrStateNotFound) { - _ = h.utils.Respond(h.ctx, s, i, responses.UserNotInVoiceChannel()) + _ = h.utils.Respond(i, responses.UserNotInVoiceChannel()) return } - channel, err := h.unlockChannel(s, voiceState.ChannelID) + channel, err := h.unlockChannel(voiceState.ChannelID) if err != nil { h.log.Error("failed to remove user limit", "error", err) return } - _ = h.utils.Respond(h.ctx, s, i, responses.UnlockedChannel(channel)) + _ = h.utils.Respond(i, responses.UnlockedChannel(channel)) } -func (h Handler) unlockChannel( - s *discordgo.Session, - channelID string, -) (*discordgo.Channel, error) { +// unlockChannel Workaround method for removing channel user limit +func (h *Handler) unlockChannel(channelID string) (*discordgo.Channel, error) { type request struct { UserLimit int `json:"user_limit"` } - resp, err := s.RequestWithBucketID( + resp, err := h.session.RequestWithBucketID( http.MethodPatch, discordgo.EndpointChannel(channelID), request{UserLimit: 0}, diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index 362ce69..897e348 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -10,7 +10,7 @@ import ( "github.com/knadh/koanf/v2" ) -func ReadConfig[T any]() T { +func ReadConfig[T any]() *T { k := koanf.New(".") if err := k.Load(file.Provider("config.yaml"), yaml.Parser()); err != nil { @@ -24,8 +24,8 @@ func ReadConfig[T any]() T { log.Println("environment variables have not been loaded") } - var cfg T - err := k.UnmarshalWithConf("", &cfg, koanf.UnmarshalConf{Tag: "conf"}) + cfg := new(T) + err := k.UnmarshalWithConf("", cfg, koanf.UnmarshalConf{Tag: "conf"}) if err != nil { log.Fatalln("failed to unmarshal config:", err) } diff --git a/internal/pkg/dbUtils/txWrapper.go b/internal/pkg/dbUtils/txWrapper.go index d9eb268..f3880f2 100644 --- a/internal/pkg/dbUtils/txWrapper.go +++ b/internal/pkg/dbUtils/txWrapper.go @@ -25,7 +25,7 @@ func NewTxWrapper( } } -func (w txWrapper) Wrap( +func (w *txWrapper) Wrap( ctx context.Context, operation Operation, ) error { @@ -53,7 +53,7 @@ func (w txWrapper) Wrap( return nil } -func (w txWrapper) rollbackTx(ctx context.Context, tx *sql.Tx) { +func (w *txWrapper) rollbackTx(ctx context.Context, tx *sql.Tx) { err := tx.Rollback() if err != nil { w.log.ErrorContext(ctx, "failed to rollback transaction", "error", err) diff --git a/internal/pkg/discordUtils/utils.go b/internal/pkg/discordUtils/utils.go index ad8ae8d..8a53d3f 100644 --- a/internal/pkg/discordUtils/utils.go +++ b/internal/pkg/discordUtils/utils.go @@ -10,20 +10,37 @@ import ( "github.com/nijeti/cinema-keeper/internal/types" ) -type Utils struct { - log *slog.Logger +type Utils interface { + GetVoiceChannelUsers( + guild types.ID, + channel types.ID, + ) ([]*discordgo.Member, error) + + Respond( + interaction *discordgo.InteractionCreate, + response *discordgo.InteractionResponse, + ) error +} + +type utils struct { + ctx context.Context + log *slog.Logger + session *discordgo.Session } func New( + ctx context.Context, log *slog.Logger, + session *discordgo.Session, ) Utils { - return Utils{ - log: log, + return &utils{ + ctx: ctx, + log: log, + session: session, } } -func (u Utils) GetVoiceChannelUsers( - s *discordgo.Session, +func (u *utils) GetVoiceChannelUsers( guild types.ID, channel types.ID, ) ([]*discordgo.Member, error) { @@ -34,7 +51,7 @@ func (u Utils) GetVoiceChannelUsers( var after string for { - members, err := s.GuildMembers(guildID, after, 1000) + members, err := u.session.GuildMembers(guildID, after, 1000) if err != nil { return nil, err } @@ -44,7 +61,9 @@ func (u Utils) GetVoiceChannelUsers( } for _, member := range members { - voiceState, err := s.State.VoiceState(guildID, member.User.ID) + voiceState, err := u.session.State.VoiceState( + guildID, member.User.ID, + ) if err != nil { if errors.Is(err, discordgo.ErrStateNotFound) { continue @@ -65,15 +84,13 @@ func (u Utils) GetVoiceChannelUsers( return users, nil } -func (u Utils) Respond( - ctx context.Context, - s *discordgo.Session, - i *discordgo.InteractionCreate, +func (u *utils) Respond( + interaction *discordgo.InteractionCreate, response *discordgo.InteractionResponse, ) error { - err := s.InteractionRespond(i.Interaction, response) + err := u.session.InteractionRespond(interaction.Interaction, response) if err != nil { - u.log.ErrorContext(ctx, "failed to respond", "error", err) + u.log.ErrorContext(u.ctx, "failed to respond", "error", err) } return err } diff --git a/internal/pkg/utils/utils.go b/internal/pkg/utils/utils.go index 7d0a492..8b9da0c 100644 --- a/internal/pkg/utils/utils.go +++ b/internal/pkg/utils/utils.go @@ -5,6 +5,6 @@ import ( ) func RandomColor() int { - const maxColorValue = 16777215 + const maxColorValue = 0xffffff return rand.IntN(maxColorValue + 1) }