mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-17 03:24:40 -07:00
Avoid race by using conditional deep copy
Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
@@ -908,7 +908,7 @@ func (c *client) processPing() {
|
||||
// If there was a cluster update since this client was created,
|
||||
// send an updated INFO protocol now.
|
||||
if srv.lastCURLsUpdate >= c.start.UnixNano() {
|
||||
c.sendInfo(c.generateClientInfoJSON(srv.info))
|
||||
c.sendInfo(c.generateClientInfoJSON(srv.copyInfo()))
|
||||
}
|
||||
c.mu.Unlock()
|
||||
srv.mu.Unlock()
|
||||
|
||||
@@ -389,7 +389,7 @@ func (s *Server) sendAsyncInfoToClients() {
|
||||
if c.opts.Protocol >= ClientProtoInfo && c.flags.isSet(firstPongSent) {
|
||||
// sendInfo takes care of checking if the connection is still
|
||||
// valid or not, so don't duplicate tests here.
|
||||
c.sendInfo(c.generateClientInfoJSON(s.info))
|
||||
c.sendInfo(c.generateClientInfoJSON(s.copyInfo()))
|
||||
}
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
@@ -708,6 +708,18 @@ func (s *Server) HTTPHandler() http.Handler {
|
||||
return s.httpHandler
|
||||
}
|
||||
|
||||
// Perform a conditional deep copy due to reference nature of ClientConnectURLs.
|
||||
// If updates are made to Info, this function should be consulted and updated.
|
||||
// Assume lock is held.
|
||||
func (s *Server) copyInfo() Info {
|
||||
info := s.info
|
||||
if info.ClientConnectURLs != nil {
|
||||
info.ClientConnectURLs = make([]string, len(s.info.ClientConnectURLs))
|
||||
copy(info.ClientConnectURLs, s.info.ClientConnectURLs)
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func (s *Server) createClient(conn net.Conn) *client {
|
||||
// Snapshot server options.
|
||||
opts := s.getOpts()
|
||||
@@ -716,7 +728,7 @@ func (s *Server) createClient(conn net.Conn) *client {
|
||||
|
||||
// Grab JSON info string
|
||||
s.mu.Lock()
|
||||
info := s.info
|
||||
info := s.copyInfo()
|
||||
s.totalClients++
|
||||
s.mu.Unlock()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user