Handle interrupts and panics to mitigate data loss

This commit introduces a deferred call to a state teardown function
This is needed to properly flush data to the backing documentbuffer
as well as to truncate its underlying store. In doing so we make
sure data loss from process termination is minimal to nil.

when ever a panic happens or a signal is thrown the call to Teardown() is made

Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
Ava Apples Affine 2024-11-30 10:49:16 -08:00
parent 9d3ca54ad4
commit d818e8c158
2 changed files with 22 additions and 8 deletions

View file

@ -48,6 +48,7 @@ const (
var eventMutex sync.RWMutex
var eventSubscriptionCache = [NumEventTypes][]chan Event{}
var eventStorageFileName string
var eventStream docbuf.DocumentBuffer
var maxEventsInMemory int
@ -65,10 +66,29 @@ func Init(eventMemCacheSize int, eventStoreFileName string) error {
return errors.Join(errors.New(BadEventStreamInit), err)
}
eventStorageFileName = eventStoreFileName
maxEventsInMemory = eventMemCacheSize
return nil
}
// return no error. we are handling SIGINT
func Teardown() {
// riskily ignore all locking....
// we are handling a termination signal after all
i, e := eventStream.Close()
if e != nil {
logging.Warn("failed to close document buffer: %s", e.Error())
logging.Warn("will attempt to truncate event store anyways")
}
e = os.Truncate(eventStorageFileName, i)
if e != nil {
logging.Error("FAILED TO TRUNCATE EVENT STORE!!")
logging.Error("You will likely have garbage data at the end of it")
logging.Error("Attempt manual correction!")
}
}
type EventType int8
const (

10
main.go
View file

@ -3,8 +3,6 @@ package main
import (
"flag"
"log"
"os"
"os/signal"
"gitlab.com/whom/bingobot/internal/config"
"gitlab.com/whom/bingobot/internal/discord"
@ -17,8 +15,6 @@ var (
)
func main() {
flag.Parse()
var err error
err = config.Init()
@ -28,6 +24,7 @@ func main() {
}
logging.Init()
flag.Parse()
if err := state.Init(
config.Get().InMemoryEventCacheSize,
@ -35,6 +32,7 @@ func main() {
); err != nil {
log.Fatalf("couldn't initialize state engine: %s", err.Error())
}
defer state.Teardown()
err = startBot()
@ -50,10 +48,6 @@ func startBot() error {
return err
}
sigch := make(chan os.Signal, 1)
signal.Notify(sigch, os.Interrupt)
<-sigch
logging.Info("shutting down gracefully", "type", "shutdown")
discord.Close()