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:
Houmgaor
2026-02-19 18:13:34 +01:00
parent ba9fce153d
commit 754b5a3bff
10 changed files with 661 additions and 79 deletions

View File

@@ -297,6 +297,15 @@ type EntranceChannelInfo struct {
Port uint16
MaxPlayers uint16
CurrentPlayers uint16
Enabled *bool // nil defaults to true for backward compatibility
}
// IsEnabled returns whether this channel is enabled. Defaults to true if Enabled is nil.
func (c *EntranceChannelInfo) IsEnabled() bool {
if c.Enabled == nil {
return true
}
return *c.Enabled
}
var ErupeConfig *Config