From fed49ba3cb1b78792e28200a8f529b7537e7fce7 Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Mon, 13 Jan 2025 15:45:07 -0800 Subject: [PATCH] refactor main, and fix bugs from initial manual run Signed-off-by: Ava Affine --- internal/confession/confession.go | 6 ++-- internal/discord/commands.go | 42 +++++++++++++++++---------- internal/state/events.go | 2 +- internal/state/state.go | 2 ++ internal/web/web.go | 1 + main.go | 48 ++++++++++++++++++++----------- 6 files changed, 66 insertions(+), 35 deletions(-) diff --git a/internal/confession/confession.go b/internal/confession/confession.go index 2681d31..81babdb 100644 --- a/internal/confession/confession.go +++ b/internal/confession/confession.go @@ -2,6 +2,7 @@ package confession import ( "errors" + "fmt" "sync" "github.com/bwmarrin/discordgo" @@ -20,7 +21,7 @@ const ( var ( // guild ID to channel ID linkLock sync.RWMutex - confessionChannelLinks map[string]state.ConfessionsChannelLinkEvent + confessionChannelLinks = make(map[string]state.ConfessionsChannelLinkEvent) ) func Start() error { @@ -36,6 +37,7 @@ func Start() error { go func() { for { ev := <- ch + logging.Info("recieved new confessional channel link") e := ev.(state.ConfessionsChannelLinkEvent) linkLock.Lock() confessionChannelLinks[e.GuildID] = e @@ -51,7 +53,7 @@ func MakeConfession(s *discordgo.Session, guildID string, content string) { link, ok := confessionChannelLinks[guildID] linkLock.RUnlock() if !ok { - logging.Error("Failed to send confession in guild %s: no link exists in map", guildID) + logging.Error(fmt.Sprintf("Failed to send confession in guild %s: no link exists in map", guildID)) return } s.ChannelMessageSend(link.ChannelID, content) diff --git a/internal/discord/commands.go b/internal/discord/commands.go index 4499a85..b194bc6 100644 --- a/internal/discord/commands.go +++ b/internal/discord/commands.go @@ -1,6 +1,7 @@ package discord import ( + "fmt" "time" "github.com/bwmarrin/discordgo" @@ -42,11 +43,18 @@ var ( i *discordgo.InteractionCreate, ) { "confessional": func(s *discordgo.Session, i *discordgo.InteractionCreate) { - state.PublishEvent(state.ConfessionsChannelLinkEvent{ + if err := state.PublishEvent(state.ConfessionsChannelLinkEvent{ GuildID: i.GuildID, ChannelID: i.ChannelID, Created: time.Now(), - }) + }); err != nil { + logging.Error(fmt.Sprintf( + "failed to publish confession channel link: %s", + err.Error(), + )) + } else { + logging.Info("published confession channel link") + } }, // handle a confession @@ -68,6 +76,10 @@ func handleCommand(s *discordgo.Session, e *discordgo.InteractionCreate) { } else { logging.Debug("no handler for command: %s", name) } + + s.InteractionRespond(e.Interaction, &discordgo.InteractionResponse{ + // TODO: Some silent ACK + }) } func registerCommands(s *discordgo.Session) { @@ -79,12 +91,12 @@ func registerCommands(s *discordgo.Session) { ) if err != nil { - logging.Error( - "Failed to register commands for guild", - guild.ID, ": ", err.Error(), - ) + logging.Error(fmt.Sprintf( + "Failed to register commands for guild %s: %s", + guild.ID, err.Error(), + )) } else { - logging.Info("Registered commands for guild ", guild.ID) + logging.Info(fmt.Sprintf("Registered commands for guild %s", guild.ID)) registeredCommands[guild.ID] = cmds } } @@ -98,15 +110,15 @@ func deregisterCommands(s *discordgo.Session) { guild, cmd.ID, ); err != nil { - logging.Error( - "Failed to delete", cmd.Name, "command (id:", cmd.ID, - ") from guild ", guild, - ) + logging.Error(fmt.Sprintf( + "Failed to delete %s command (id: %s) from guild %s", + cmd.Name, cmd.ID, guild, + )) } else { - logging.Info( - "Deregistered command ", cmd.Name,"(id:", cmd.ID, - ") from guild ", guild, - ) + logging.Info(fmt.Sprintf( + "Deregistered command %s (id: %s) from guild %s", + cmd.Name, cmd.ID, guild, + )) } } } diff --git a/internal/state/events.go b/internal/state/events.go index 285db51..44ad0f4 100644 --- a/internal/state/events.go +++ b/internal/state/events.go @@ -259,7 +259,7 @@ func (e ConfessionsChannelLinkEvent) Data() map[string]string { } func (e ConfessionsChannelLinkEvent) Validate() error { - if len(e.ChannelID) > 1 || len(e.GuildID) > 1 { + if len(e.ChannelID) <= 1 || len(e.GuildID) <= 1 { return errors.New(BadConfessionsLinkEventError) } diff --git a/internal/state/state.go b/internal/state/state.go index 9b94ec2..cc439f5 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -159,6 +159,7 @@ func Start() error { // return no error. we are handling SIGINT func Teardown() { + logging.Warn("Tearing down state engine") // riskily ignore all locking.... // we are handling a termination signal after all i, e := eventStream.Close() @@ -167,6 +168,7 @@ func Teardown() { logging.Warn("will attempt to truncate event store anyways") } + logging.Warn("teardown: events flushed") e = os.Truncate(eventStorageFileName, i) if e != nil { logging.Error("FAILED TO TRUNCATE EVENT STORE!!") diff --git a/internal/web/web.go b/internal/web/web.go index 38051e6..fbe65eb 100644 --- a/internal/web/web.go +++ b/internal/web/web.go @@ -14,6 +14,7 @@ func Start() error { http.HandleFunc("/", HandleHttpRequest) go logging.Error(http.ListenAndServe(frag, nil).Error()) + logging.Debug("Web handlers started") return nil } diff --git a/main.go b/main.go index 0528e1c..a91fdb4 100644 --- a/main.go +++ b/main.go @@ -3,8 +3,11 @@ package main import ( "flag" "log" + "os" + "os/signal" "gitlab.com/whom/bingobot/internal/activity" + "gitlab.com/whom/bingobot/internal/confession" "gitlab.com/whom/bingobot/internal/config" "gitlab.com/whom/bingobot/internal/discord" "gitlab.com/whom/bingobot/internal/logging" @@ -28,6 +31,7 @@ func main() { logging.Init() flag.Parse() + logging.Info("startup: initializing state engine") if err := state.Init( config.Get().InMemoryEventCacheSize, config.Get().PersistentCacheStore, @@ -35,35 +39,45 @@ func main() { log.Fatalf("couldn't initialize state engine: %s", err.Error()) } + logging.Info("startup: starting activity module") if err := activity.Start(); err != nil { // TODO: handle gracefully and continue? log.Fatalf("failed to start activity module: %s", err.Error()) } - if err := web.Start(); err != nil { - log.Fatalf("failed to start local web server: %s", err.Error()) + logging.Info("startup: starting confession module") + if err := confession.Start(); err != nil { + // TODO: handle gracefully and continue? + log.Fatalf("failed to start confession module: %s", err.Error()) } + logging.Info("startup: starting web module") + go func() { + if err := web.Start(); err != nil { + log.Fatalf("failed to start local web server: %s", err.Error()) + } + }() + // start this LAST + logging.Info("startup: starting state engine") if err := state.Start(); err != nil { log.Fatalf("failed to start state machine: %s", err.Error()) } - defer state.Teardown() - if err := startBot(); err != nil { + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt) + go func(){ + for _ = range c { + state.Teardown() + discord.Close() + os.Exit(1) + } + }() + + logging.Info("startup: connecting to discord") + if err := discord.Connect(*token); err != nil { log.Fatal(err) } -} - -func startBot() error { - err := discord.Connect(*token) - - if err != nil { - return err - } - - logging.Info("shutting down gracefully", "type", "shutdown") - discord.Close() - - return nil + + for {} }