Don't lock the subscriber list longer than necessary

This commit is contained in:
Noah 2023-07-29 17:54:49 -07:00
parent f3517bec87
commit 84da298c12
2 changed files with 9 additions and 12 deletions

View File

@ -137,9 +137,7 @@ func (s *Server) KickAllCommand() {
}) })
// Disconnect everybody. // Disconnect everybody.
s.subscribersMu.RLock() for _, sub := range s.IterSubscribers() {
defer s.subscribersMu.RUnlock()
for _, sub := range s.IterSubscribers(true) {
if !sub.authenticated { if !sub.authenticated {
continue continue
} }

View File

@ -233,9 +233,7 @@ func (s *Server) AddSubscriber(sub *Subscriber) {
// GetSubscriber by username. // GetSubscriber by username.
func (s *Server) GetSubscriber(username string) (*Subscriber, error) { func (s *Server) GetSubscriber(username string) (*Subscriber, error) {
s.subscribersMu.RLock() for _, sub := range s.IterSubscribers() {
defer s.subscribersMu.RUnlock()
for _, sub := range s.IterSubscribers(true) {
if sub.Username == username { if sub.Username == username {
return sub, nil return sub, nil
} }
@ -310,9 +308,11 @@ func (s *Server) Broadcast(msg Message) {
log.Debug("Broadcast: %+v", msg) log.Debug("Broadcast: %+v", msg)
} }
s.subscribersMu.RLock() // Get the list of users who are online NOW, so we don't hold the mutex lock too long.
defer s.subscribersMu.RUnlock() // Example: sending a fat GIF to a large audience could hang up the server for a long
for _, sub := range s.IterSubscribers(true) { // time until every copy of the GIF has been sent.
var subs = s.IterSubscribers()
for _, sub := range subs {
if !sub.authenticated { if !sub.authenticated {
continue continue
} }
@ -331,11 +331,10 @@ func (s *Server) Broadcast(msg Message) {
func (s *Server) SendTo(username string, msg Message) error { func (s *Server) SendTo(username string, msg Message) error {
log.Debug("SendTo(%s): %+v", username, msg) log.Debug("SendTo(%s): %+v", username, msg)
username = strings.TrimPrefix(username, "@") username = strings.TrimPrefix(username, "@")
s.subscribersMu.RLock()
defer s.subscribersMu.RUnlock()
var found bool var found bool
for _, sub := range s.IterSubscribers(true) { var subs = s.IterSubscribers()
for _, sub := range subs {
if sub.Username == username { if sub.Username == username {
found = true found = true
sub.SendJSON(Message{ sub.SendJSON(Message{