@@ -3,6 +3,7 @@ package ws
33import (
44 "encoding/json"
55 "log/slog"
6+ "sync"
67
78 "linux-iso-manager/internal/models"
89)
@@ -31,6 +32,9 @@ type Hub struct {
3132 // Registered clients
3233 clients map [* Client ]bool
3334
35+ // Protects clients map for concurrent read access
36+ mu sync.RWMutex
37+
3438 // Inbound messages from clients
3539 broadcast chan []byte
3640
@@ -56,18 +60,27 @@ func (h *Hub) Run() {
5660 for {
5761 select {
5862 case client := <- h .register :
63+ h .mu .Lock ()
5964 h .clients [client ] = true
60- slog .Debug ("websocket client connected" , slog .Int ("total_clients" , len (h .clients )))
65+ count := len (h .clients )
66+ h .mu .Unlock ()
67+ slog .Debug ("websocket client connected" , slog .Int ("total_clients" , count ))
6168
6269 case client := <- h .unregister :
70+ h .mu .Lock ()
6371 if _ , ok := h .clients [client ]; ok {
6472 delete (h .clients , client )
6573 close (client .send )
66- slog .Debug ("websocket client disconnected" , slog .Int ("total_clients" , len (h .clients )))
74+ count := len (h .clients )
75+ h .mu .Unlock ()
76+ slog .Debug ("websocket client disconnected" , slog .Int ("total_clients" , count ))
77+ } else {
78+ h .mu .Unlock ()
6779 }
6880
6981 case message := <- h .broadcast :
7082 // Broadcast to all connected clients
83+ h .mu .Lock ()
7184 for client := range h .clients {
7285 select {
7386 case client .send <- message :
@@ -77,6 +90,7 @@ func (h *Hub) Run() {
7790 delete (h .clients , client )
7891 }
7992 }
93+ h .mu .Unlock ()
8094 }
8195 }
8296}
@@ -113,5 +127,7 @@ func (h *Hub) BroadcastProgress(isoID string, progress int, status models.ISOSta
113127
114128// ClientCount returns the number of connected clients.
115129func (h * Hub ) ClientCount () int {
130+ h .mu .RLock ()
131+ defer h .mu .RUnlock ()
116132 return len (h .clients )
117133}
0 commit comments