refactor main, and fix bugs from initial manual run

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2025-01-13 15:45:07 -08:00
parent 55f9725af1
commit fed49ba3cb
6 changed files with 66 additions and 35 deletions

View file

@ -2,6 +2,7 @@ package confession
import ( import (
"errors" "errors"
"fmt"
"sync" "sync"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
@ -20,7 +21,7 @@ const (
var ( var (
// guild ID to channel ID // guild ID to channel ID
linkLock sync.RWMutex linkLock sync.RWMutex
confessionChannelLinks map[string]state.ConfessionsChannelLinkEvent confessionChannelLinks = make(map[string]state.ConfessionsChannelLinkEvent)
) )
func Start() error { func Start() error {
@ -36,6 +37,7 @@ func Start() error {
go func() { go func() {
for { for {
ev := <- ch ev := <- ch
logging.Info("recieved new confessional channel link")
e := ev.(state.ConfessionsChannelLinkEvent) e := ev.(state.ConfessionsChannelLinkEvent)
linkLock.Lock() linkLock.Lock()
confessionChannelLinks[e.GuildID] = e confessionChannelLinks[e.GuildID] = e
@ -51,7 +53,7 @@ func MakeConfession(s *discordgo.Session, guildID string, content string) {
link, ok := confessionChannelLinks[guildID] link, ok := confessionChannelLinks[guildID]
linkLock.RUnlock() linkLock.RUnlock()
if !ok { 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 return
} }
s.ChannelMessageSend(link.ChannelID, content) s.ChannelMessageSend(link.ChannelID, content)

View file

@ -1,6 +1,7 @@
package discord package discord
import ( import (
"fmt"
"time" "time"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
@ -42,11 +43,18 @@ var (
i *discordgo.InteractionCreate, i *discordgo.InteractionCreate,
) { ) {
"confessional": func(s *discordgo.Session, i *discordgo.InteractionCreate) { "confessional": func(s *discordgo.Session, i *discordgo.InteractionCreate) {
state.PublishEvent(state.ConfessionsChannelLinkEvent{ if err := state.PublishEvent(state.ConfessionsChannelLinkEvent{
GuildID: i.GuildID, GuildID: i.GuildID,
ChannelID: i.ChannelID, ChannelID: i.ChannelID,
Created: time.Now(), 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 // handle a confession
@ -68,6 +76,10 @@ func handleCommand(s *discordgo.Session, e *discordgo.InteractionCreate) {
} else { } else {
logging.Debug("no handler for command: %s", name) logging.Debug("no handler for command: %s", name)
} }
s.InteractionRespond(e.Interaction, &discordgo.InteractionResponse{
// TODO: Some silent ACK
})
} }
func registerCommands(s *discordgo.Session) { func registerCommands(s *discordgo.Session) {
@ -79,12 +91,12 @@ func registerCommands(s *discordgo.Session) {
) )
if err != nil { if err != nil {
logging.Error( logging.Error(fmt.Sprintf(
"Failed to register commands for guild", "Failed to register commands for guild %s: %s",
guild.ID, ": ", err.Error(), guild.ID, err.Error(),
) ))
} else { } else {
logging.Info("Registered commands for guild ", guild.ID) logging.Info(fmt.Sprintf("Registered commands for guild %s", guild.ID))
registeredCommands[guild.ID] = cmds registeredCommands[guild.ID] = cmds
} }
} }
@ -98,15 +110,15 @@ func deregisterCommands(s *discordgo.Session) {
guild, guild,
cmd.ID, cmd.ID,
); err != nil { ); err != nil {
logging.Error( logging.Error(fmt.Sprintf(
"Failed to delete", cmd.Name, "command (id:", cmd.ID, "Failed to delete %s command (id: %s) from guild %s",
") from guild ", guild, cmd.Name, cmd.ID, guild,
) ))
} else { } else {
logging.Info( logging.Info(fmt.Sprintf(
"Deregistered command ", cmd.Name,"(id:", cmd.ID, "Deregistered command %s (id: %s) from guild %s",
") from guild ", guild, cmd.Name, cmd.ID, guild,
) ))
} }
} }
} }

View file

@ -259,7 +259,7 @@ func (e ConfessionsChannelLinkEvent) Data() map[string]string {
} }
func (e ConfessionsChannelLinkEvent) Validate() error { 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) return errors.New(BadConfessionsLinkEventError)
} }

View file

@ -159,6 +159,7 @@ func Start() error {
// return no error. we are handling SIGINT // return no error. we are handling SIGINT
func Teardown() { func Teardown() {
logging.Warn("Tearing down state engine")
// riskily ignore all locking.... // riskily ignore all locking....
// we are handling a termination signal after all // we are handling a termination signal after all
i, e := eventStream.Close() i, e := eventStream.Close()
@ -167,6 +168,7 @@ func Teardown() {
logging.Warn("will attempt to truncate event store anyways") logging.Warn("will attempt to truncate event store anyways")
} }
logging.Warn("teardown: events flushed")
e = os.Truncate(eventStorageFileName, i) e = os.Truncate(eventStorageFileName, i)
if e != nil { if e != nil {
logging.Error("FAILED TO TRUNCATE EVENT STORE!!") logging.Error("FAILED TO TRUNCATE EVENT STORE!!")

View file

@ -14,6 +14,7 @@ func Start() error {
http.HandleFunc("/", HandleHttpRequest) http.HandleFunc("/", HandleHttpRequest)
go logging.Error(http.ListenAndServe(frag, nil).Error()) go logging.Error(http.ListenAndServe(frag, nil).Error())
logging.Debug("Web handlers started")
return nil return nil
} }

48
main.go
View file

@ -3,8 +3,11 @@ package main
import ( import (
"flag" "flag"
"log" "log"
"os"
"os/signal"
"gitlab.com/whom/bingobot/internal/activity" "gitlab.com/whom/bingobot/internal/activity"
"gitlab.com/whom/bingobot/internal/confession"
"gitlab.com/whom/bingobot/internal/config" "gitlab.com/whom/bingobot/internal/config"
"gitlab.com/whom/bingobot/internal/discord" "gitlab.com/whom/bingobot/internal/discord"
"gitlab.com/whom/bingobot/internal/logging" "gitlab.com/whom/bingobot/internal/logging"
@ -28,6 +31,7 @@ func main() {
logging.Init() logging.Init()
flag.Parse() flag.Parse()
logging.Info("startup: initializing state engine")
if err := state.Init( if err := state.Init(
config.Get().InMemoryEventCacheSize, config.Get().InMemoryEventCacheSize,
config.Get().PersistentCacheStore, config.Get().PersistentCacheStore,
@ -35,35 +39,45 @@ func main() {
log.Fatalf("couldn't initialize state engine: %s", err.Error()) log.Fatalf("couldn't initialize state engine: %s", err.Error())
} }
logging.Info("startup: starting activity module")
if err := activity.Start(); err != nil { if err := activity.Start(); err != nil {
// TODO: handle gracefully and continue? // TODO: handle gracefully and continue?
log.Fatalf("failed to start activity module: %s", err.Error()) log.Fatalf("failed to start activity module: %s", err.Error())
} }
if err := web.Start(); err != nil { logging.Info("startup: starting confession module")
log.Fatalf("failed to start local web server: %s", err.Error()) 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 // start this LAST
logging.Info("startup: starting state engine")
if err := state.Start(); err != nil { if err := state.Start(); err != nil {
log.Fatalf("failed to start state machine: %s", err.Error()) 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) log.Fatal(err)
} }
}
for {}
func startBot() error {
err := discord.Connect(*token)
if err != nil {
return err
}
logging.Info("shutting down gracefully", "type", "shutdown")
discord.Close()
return nil
} }