From 73c42232fcbf1e236d3a89af335f03b0bc410343 Mon Sep 17 00:00:00 2001 From: Devon Hudson Date: Thu, 12 Jan 2023 12:20:03 -0700 Subject: [PATCH] Fix race in refactored statistics --- federationapi/statistics/statistics.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/federationapi/statistics/statistics.go b/federationapi/statistics/statistics.go index 7c1258d09..430819642 100644 --- a/federationapi/statistics/statistics.go +++ b/federationapi/statistics/statistics.go @@ -83,7 +83,9 @@ func (s *Statistics) ForServer(serverName gomatrixserverlib.ServerName) *ServerS if err != nil { logrus.WithError(err).Errorf("Failed to get relay server list for %q", serverName) } else { + server.relayMutex.Lock() server.knownRelayServers = knownRelayServers + server.relayMutex.Unlock() } } return server @@ -112,6 +114,7 @@ type ServerStatistics struct { backoffNotifier func() // notifies destination queue when backoff completes notifierMutex sync.Mutex knownRelayServers []gomatrixserverlib.ServerName + relayMutex sync.Mutex } const maxJitterMultiplier = 1.4 @@ -207,8 +210,8 @@ func (s *ServerStatistics) Failure() (time.Time, bool) { s.backoffUntil.Store(until) s.statistics.backoffMutex.Lock() - defer s.statistics.backoffMutex.Unlock() s.statistics.backoffTimers[s.serverName] = time.AfterFunc(time.Until(until), s.backoffFinished) + s.statistics.backoffMutex.Unlock() } return s.backoffUntil.Load().(time.Time), false @@ -302,6 +305,8 @@ func (s *ServerStatistics) SuccessCount() uint32 { // KnownRelayServers returns the list of relay servers associated with this // server. func (s *ServerStatistics) KnownRelayServers() []gomatrixserverlib.ServerName { + s.relayMutex.Lock() + defer s.relayMutex.Unlock() return s.knownRelayServers } @@ -324,13 +329,18 @@ func (s *ServerStatistics) AddRelayServers(relayServers []gomatrixserverlib.Serv for _, newServer := range uniqueList { alreadyKnown := false - for _, srv := range s.knownRelayServers { + knownRelayServers := s.KnownRelayServers() + for _, srv := range knownRelayServers { if srv == newServer { alreadyKnown = true } } if !alreadyKnown { - s.knownRelayServers = append(s.knownRelayServers, newServer) + { + s.relayMutex.Lock() + s.knownRelayServers = append(s.knownRelayServers, newServer) + s.relayMutex.Unlock() + } } } }