Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory optimizations #22

Merged
merged 1 commit into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/migrator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
31 changes: 14 additions & 17 deletions cmd/service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 2 additions & 2 deletions internal/db/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
12 changes: 6 additions & 6 deletions internal/db/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions internal/db/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
8 changes: 4 additions & 4 deletions internal/db/quotes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
38 changes: 19 additions & 19 deletions internal/discord/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
14 changes: 7 additions & 7 deletions internal/discord/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
2 changes: 1 addition & 1 deletion internal/discord/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

type Handler interface {
Handle(s *discordgo.Session, i *discordgo.InteractionCreate)
Handle(i *discordgo.InteractionCreate)
}

type Command struct {
Expand Down
47 changes: 21 additions & 26 deletions internal/handlers/cast/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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")
Expand Down
Loading