Resilient session storage: recover on failed startup

This commit is contained in:
pounceandmiss 2026-05-24 07:00:52 -07:00
parent a08719db2e
commit 9766f6cc7f

View file

@ -5,6 +5,7 @@ import (
"regexp"
"strconv"
"sync"
"sync/atomic"
"time"
"dev.narayana.im/narayana/telegabber/badger"
@ -21,6 +22,10 @@ import (
var tgConf config.TelegramConfig
var sessions map[string]*telegram.Client
var db *persistence.SessionsYamlDB
// componentEverConnected gates SaveSessions in Close(): a shutdown that
// never connected must not overwrite persisted YAML with an empty map.
var componentEverConnected atomic.Bool
var sessionLock sync.Mutex
const (
@ -97,6 +102,7 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig, idsPath stri
}
sm := xmpp.NewStreamManager(component, func(s xmpp.Sender) {
componentEverConnected.Store(true)
go heartbeat(component)
})
@ -247,7 +253,9 @@ func SaveSessions() {
}, persistence.SessionMarshaller)
}
// Close gracefully terminates the component and saves active sessions
// Close gracefully terminates the component and saves active sessions.
// If the component never reached steady state, SaveSessions is skipped
// to avoid overwriting persisted state with the empty-at-startup map.
func Close(component *xmpp.Component) {
log.Error("Disconnecting...")
@ -258,8 +266,11 @@ func Close(component *xmpp.Component) {
}
sessionLock.Unlock()
// save sessions
if componentEverConnected.Load() {
SaveSessions()
} else {
log.Warn("Close: component never connected, skipping SaveSessions to preserve on-disk state")
}
// flush the ids database
gateway.IdsDB.Close()