mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-27 01:53:19 +01:00
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:
@@ -34,9 +34,7 @@ func TestHandleMsgSysEnumerateClient(t *testing.T) {
|
||||
s2.charID = 200
|
||||
stage.clients[s1] = 100
|
||||
stage.clients[s2] = 200
|
||||
server.stagesLock.Lock()
|
||||
server.stages[stageID] = stage
|
||||
server.stagesLock.Unlock()
|
||||
server.stages.Store(stageID, stage)
|
||||
},
|
||||
wantClientCount: 2,
|
||||
wantFailure: false,
|
||||
@@ -50,9 +48,7 @@ func TestHandleMsgSysEnumerateClient(t *testing.T) {
|
||||
stage.reservedClientSlots[100] = false // Not ready
|
||||
stage.reservedClientSlots[200] = true // Ready
|
||||
stage.reservedClientSlots[300] = false // Not ready
|
||||
server.stagesLock.Lock()
|
||||
server.stages[stageID] = stage
|
||||
server.stagesLock.Unlock()
|
||||
server.stages.Store(stageID, stage)
|
||||
},
|
||||
wantClientCount: 2, // Only not-ready clients
|
||||
wantFailure: false,
|
||||
@@ -66,9 +62,7 @@ func TestHandleMsgSysEnumerateClient(t *testing.T) {
|
||||
stage.reservedClientSlots[100] = false // Not ready
|
||||
stage.reservedClientSlots[200] = true // Ready
|
||||
stage.reservedClientSlots[300] = true // Ready
|
||||
server.stagesLock.Lock()
|
||||
server.stages[stageID] = stage
|
||||
server.stagesLock.Unlock()
|
||||
server.stages.Store(stageID, stage)
|
||||
},
|
||||
wantClientCount: 2, // Only ready clients
|
||||
wantFailure: false,
|
||||
@@ -79,9 +73,7 @@ func TestHandleMsgSysEnumerateClient(t *testing.T) {
|
||||
getType: 0,
|
||||
setupStage: func(server *Server, stageID string) {
|
||||
stage := NewStage(stageID)
|
||||
server.stagesLock.Lock()
|
||||
server.stages[stageID] = stage
|
||||
server.stagesLock.Unlock()
|
||||
server.stages.Store(stageID, stage)
|
||||
},
|
||||
wantClientCount: 0,
|
||||
wantFailure: false,
|
||||
@@ -104,11 +96,6 @@ func TestHandleMsgSysEnumerateClient(t *testing.T) {
|
||||
mock := &MockCryptConn{sentPackets: make([][]byte, 0)}
|
||||
s := createTestSession(mock)
|
||||
|
||||
// Initialize stages map if needed
|
||||
if s.server.stages == nil {
|
||||
s.server.stages = make(map[string]*Stage)
|
||||
}
|
||||
|
||||
// Setup stage
|
||||
tt.setupStage(s.server, tt.stageID)
|
||||
|
||||
@@ -389,7 +376,6 @@ func TestEnumerateClient_ConcurrentAccess(t *testing.T) {
|
||||
logger, _ := zap.NewDevelopment()
|
||||
server := &Server{
|
||||
logger: logger,
|
||||
stages: make(map[string]*Stage),
|
||||
erupeConfig: &cfg.Config{
|
||||
DebugOptions: cfg.DebugOptions{
|
||||
LogOutboundMessages: false,
|
||||
@@ -408,9 +394,7 @@ func TestEnumerateClient_ConcurrentAccess(t *testing.T) {
|
||||
stage.clients[sess] = i * 100
|
||||
}
|
||||
|
||||
server.stagesLock.Lock()
|
||||
server.stages[stageID] = stage
|
||||
server.stagesLock.Unlock()
|
||||
server.stages.Store(stageID, stage)
|
||||
|
||||
// Run concurrent enumerations
|
||||
done := make(chan bool, 5)
|
||||
@@ -562,7 +546,6 @@ func BenchmarkEnumerateClients(b *testing.B) {
|
||||
logger, _ := zap.NewDevelopment()
|
||||
server := &Server{
|
||||
logger: logger,
|
||||
stages: make(map[string]*Stage),
|
||||
}
|
||||
|
||||
stageID := "bench_stage"
|
||||
@@ -576,7 +559,7 @@ func BenchmarkEnumerateClients(b *testing.B) {
|
||||
stage.clients[sess] = i
|
||||
}
|
||||
|
||||
server.stages[stageID] = stage
|
||||
server.stages.Store(stageID, stage)
|
||||
|
||||
mock := &MockCryptConn{sentPackets: make([][]byte, 0)}
|
||||
s := createTestSession(mock)
|
||||
|
||||
Reference in New Issue
Block a user