BrokerDetails.clientDisconnect (bool) is written by Disconnect → disconnectClientByIdentifier (amqp091.go:1337) and concurrently read by the background connectionWatcher goroutine spawned in Connect (amqp091.go:511). The reads sit in the outer watcher loop (amqp091.go:1797), the inner reconnect loop (amqp091.go:1817), and the connect() early-out (amqp091.go:1863). None of these accesses are synchronized — the sync.Mutex already on BrokerDetails guards bd.state but not this flag.
The race detector reliably flags it during Test_StreamRetry, and as a side-effect it also surfaces under several other tests that exercise the Connect/Disconnect path (Test_Disconnect, Test_SubscribeStream*).
The streamConnectionShim in streamshim.go:40 already uses atomic.Bool for the analogous flag, so the fix is to mirror that pattern on BrokerDetails.
BrokerDetails.clientDisconnect(bool) is written byDisconnect→disconnectClientByIdentifier(amqp091.go:1337) and concurrently read by the backgroundconnectionWatchergoroutine spawned inConnect(amqp091.go:511). The reads sit in the outer watcher loop (amqp091.go:1797), the inner reconnect loop (amqp091.go:1817), and theconnect()early-out (amqp091.go:1863). None of these accesses are synchronized — thesync.Mutexalready onBrokerDetailsguardsbd.statebut not this flag.The race detector reliably flags it during
Test_StreamRetry, and as a side-effect it also surfaces under several other tests that exercise theConnect/Disconnectpath (Test_Disconnect,Test_SubscribeStream*).The
streamConnectionShiminstreamshim.go:40already usesatomic.Boolfor the analogous flag, so the fix is to mirror that pattern onBrokerDetails.