mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-26 09:33:02 +01:00
feat(channelserver): decouple channel servers for independent operation (#33)
Enable multiple Erupe instances to share a single PostgreSQL database without destroying each other's state, fix existing data races in cross-channel access, and lay groundwork for future distributed channel server deployments. Phase 1 — DB safety: - Scope DELETE FROM servers/sign_sessions to this instance's server IDs - Fix ci++ bug where failed channel start shifted subsequent IDs Phase 2 — Fix data races in cross-channel access: - Lock sessions map in FindSessionByCharID and DisconnectUser - Lock stagesLock in handleMsgSysLockGlobalSema - Snapshot sessions/stages under lock in TransitMessage types 1-4 - Lock channel when finding mail notification targets Phase 3 — ChannelRegistry interface: - Define ChannelRegistry interface with 7 cross-channel operations - Implement LocalChannelRegistry with proper locking - Add SessionSnapshot/StageSnapshot immutable copy types - Delegate WorldcastMHF, FindSessionByCharID, DisconnectUser to Registry - Migrate LockGlobalSema and guild mail handlers to use Registry - Add comprehensive tests including concurrent access Phase 4 — Per-channel enable/disable: - Add Enabled *bool to EntranceChannelInfo (nil defaults to true) - Skip disabled channels in startup loop, preserving ID stability - Add IsEnabled() helper with backward-compatible default - Update config.example.json with Enabled field
This commit is contained in:
38
main.go
38
main.go
@@ -16,6 +16,7 @@ import (
|
||||
"erupe-ce/server/discordbot"
|
||||
"erupe-ce/server/entranceserver"
|
||||
"erupe-ce/server/signserver"
|
||||
"strings"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
@@ -129,11 +130,30 @@ func main() {
|
||||
}
|
||||
logger.Info("Database: Started successfully")
|
||||
|
||||
// Clear stale data
|
||||
if config.DebugOptions.ProxyPort == 0 {
|
||||
_ = db.MustExec("DELETE FROM sign_sessions")
|
||||
// Pre-compute all server IDs this instance will own, so we only
|
||||
// delete our own rows (safe for multi-instance on the same DB).
|
||||
var ownedServerIDs []string
|
||||
{
|
||||
si := 0
|
||||
for _, ee := range config.Entrance.Entries {
|
||||
ci := 0
|
||||
for range ee.Channels {
|
||||
sid := (4096 + si*256) + (16 + ci)
|
||||
ownedServerIDs = append(ownedServerIDs, fmt.Sprint(sid))
|
||||
ci++
|
||||
}
|
||||
si++
|
||||
}
|
||||
}
|
||||
|
||||
// Clear stale data scoped to this instance's server IDs
|
||||
if len(ownedServerIDs) > 0 {
|
||||
idList := strings.Join(ownedServerIDs, ",")
|
||||
if config.DebugOptions.ProxyPort == 0 {
|
||||
_ = db.MustExec("DELETE FROM sign_sessions WHERE server_id IN (" + idList + ")")
|
||||
}
|
||||
_ = db.MustExec("DELETE FROM servers WHERE server_id IN (" + idList + ")")
|
||||
}
|
||||
_ = db.MustExec("DELETE FROM servers")
|
||||
_ = db.MustExec(`UPDATE guild_characters SET treasure_hunt=NULL`)
|
||||
|
||||
// Clean the DB if the option is on.
|
||||
@@ -213,6 +233,12 @@ func main() {
|
||||
for j, ee := range config.Entrance.Entries {
|
||||
for i, ce := range ee.Channels {
|
||||
sid := (4096 + si*256) + (16 + ci)
|
||||
if !ce.IsEnabled() {
|
||||
logger.Info(fmt.Sprintf("Channel %d (%d): Disabled via config", count, ce.Port))
|
||||
ci++
|
||||
count++
|
||||
continue
|
||||
}
|
||||
c := *channelserver.NewServer(&channelserver.Config{
|
||||
ID: uint16(sid),
|
||||
Logger: logger.Named("channel-" + fmt.Sprint(count)),
|
||||
@@ -237,9 +263,9 @@ func main() {
|
||||
)
|
||||
channels = append(channels, &c)
|
||||
logger.Info(fmt.Sprintf("Channel %d (%d): Started successfully", count, ce.Port))
|
||||
ci++
|
||||
count++
|
||||
}
|
||||
ci++
|
||||
}
|
||||
ci = 0
|
||||
si++
|
||||
@@ -248,8 +274,10 @@ func main() {
|
||||
// Register all servers in DB
|
||||
_ = db.MustExec(channelQuery)
|
||||
|
||||
registry := channelserver.NewLocalChannelRegistry(channels)
|
||||
for _, c := range channels {
|
||||
c.Channels = channels
|
||||
c.Registry = registry
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user