Skip to content

Commit

Permalink
Memory optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
NiJeTi committed Jul 23, 2024
1 parent 547bb65 commit fe4e063
Show file tree
Hide file tree
Showing 20 changed files with 196 additions and 192 deletions.
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

0 comments on commit fe4e063

Please sign in to comment.