refactor(channelserver): replace global stagesLock with sync.Map-backed StageMap

The global stagesLock sync.RWMutex protected map[string]*Stage, causing
all stage operations to contend on a single lock even for unrelated
stages. Any stage creation or deletion blocked all reads server-wide.

Replace with a typed StageMap wrapper around sync.Map which provides
lock-free reads and allows concurrent writes to disjoint keys. Per-stage
sync.RWMutex remains unchanged for protecting individual stage state.

StageMap exposes Get, GetOrCreate, StoreIfAbsent, Store, Delete, and
Range methods. Updated ~50 call sites across 6 production files and
9 test files.
This commit is contained in:
Houmgaor
2026-02-22 15:47:21 +01:00
parent 2a5cd50e3f
commit ad4afb4d3b
15 changed files with 207 additions and 221 deletions

View File

@@ -56,7 +56,6 @@ func createTestServer() *Server {
ID: 1,
logger: logger,
sessions: make(map[net.Conn]*Session),
stages: make(map[string]*Stage),
semaphore: make(map[string]*Semaphore),
questCache: NewQuestCache(0),
erupeConfig: &cfg.Config{
@@ -125,7 +124,7 @@ func TestNewServer(t *testing.T) {
}
for _, stageID := range expectedStages {
if _, exists := server.stages[stageID]; !exists {
if _, exists := server.stages.Get(stageID); !exists {
t.Errorf("Default stage %s not initialized", stageID)
}
}
@@ -682,9 +681,7 @@ func TestFindObjectByChar(t *testing.T) {
stage.objects[1] = obj1
stage.objects[2] = obj2
server.stagesLock.Lock()
server.stages["test_stage"] = stage
server.stagesLock.Unlock()
server.stages.Store("test_stage", stage)
tests := []struct {
name string