atomic-websocket-broadcast-double-lock.md 1.6 KB

broadcastVisitors: двойной проход по map под lock

Контекст: В WSHub.broadcastVisitors было два последовательных прохода по h.clients под одним lock — сначала сбор visitors, затем сбор clients. Между проходами состояние не меняется (lock удерживается), но второй проход избыточен.

Проблема

// Было: два прохода под одним lock
h.mu.Lock()
for c := range h.clients {           // 1-й проход: сбор visitors
    visitors = append(visitors, ...)
}
for c := range h.clients {           // 2-й проход: сбор clients (дубликат)
    clients = append(clients, c)
}
h.mu.Unlock()
  1. Два прохода по map[*Client]bool — лишняя работа
  2. После unlock рассылка идёт по снэпшоту clients — состояние может устареть (client уже отключился), но это приемлемо

Решение

Один проход:

h.mu.Lock()
for c := range h.clients {
    visitors = append(visitors, VisitorDot{...})
    clients = append(clients, c)
}
h.mu.Unlock()

Файл: backend/internal/handlers/websocket.go:91-106

Связанные заметки

  • [[architecture-overview]] — таблица P2
  • [[atomic-websocket-origin-check]] — WebSocket origin check

Источник

Code review 2026-07-01, P2 fix.

#backend #websocket #concurrency #performance