Skip to content

fix(amqp091): close BrokerDetails.state and Test_Retry races#104

Draft
miotte wants to merge 1 commit into
mainfrom
miotte-pr8
Draft

fix(amqp091): close BrokerDetails.state and Test_Retry races#104
miotte wants to merge 1 commit into
mainfrom
miotte-pr8

Conversation

@miotte
Copy link
Copy Markdown
Contributor

@miotte miotte commented May 22, 2026

Fixes #103

Summary

  • Convert BrokerDetails.state from uint16 to atomic.Uint32 so all reads/writes synchronize, and drop the now-redundant Lock()/Unlock() blocks around state-only writes in connectionWatcher. Mirrors the pattern PR fix(amqp091): close race on BrokerDetails.clientDisconnect #102 applies to clientDisconnect.
  • Remove the redundant bd.tlsConfig = prov.tlsConfig write in getBrokerDetails — the constructor already sets it (amqp091.go:458) and prov.tlsConfig never changes after NewAMQP091Provider, so the write only created a race against the unlocked read in connect().
  • Move the mm.Headers = ... assignment in Test_Retry ahead of the goroutine that sends mm on msgs, so the value is fully populated before it is sent.

Test plan

  • go test -race -run "Test_Retry|Test_WaitForConnect|Test_connect_connecting_" -count=5 ./internal/provider/connectors/amqp091/...
  • go test ./internal/provider/connectors/amqp091/... (no -race) to confirm no behavior change
  • go vet ./...

…nect, and Test_connect_connecting_*

Three pre-existing races surfaced under -race in this package:

- BrokerDetails.state was a uint16 written under bd.Mutex by connect()
  and connectionWatcher() but read without the lock from WaitForConnect,
  queueSubscribe, Publish, and connect()'s own CONNECTING fast-path
  check.  Converted to atomic.Uint32 so all reads/writes synchronize,
  and dropped the now-redundant Lock()/Unlock() around state-only
  writes in connectionWatcher.
- getBrokerDetails() unconditionally reassigned bd.tlsConfig on every
  call, racing with concurrent reads of bd.tlsConfig in connect().  The
  assignment was redundant: BrokerDetails is constructed with
  tlsConfig: prov.tlsConfig and prov.tlsConfig is never reassigned
  after NewAMQP091Provider, so removing the write fixes the race
  without changing behavior.
- Test_Retry built an amqp091Message, started a goroutine that sent it
  on a channel, and only then mutated mm.Headers from the test
  goroutine.  Moved the Headers assignment ahead of the goroutine so
  the value is fully populated before it is sent.

Test_Retry, Test_WaitForConnect, Test_connect_connecting_connected,
Test_connect_connecting_closed, and Test_connect_connecting_disconnected
now pass under \`go test -race\`.

Signed-off-by: Michael Otteni <MichaelGOtteni@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Races in BrokerDetails.state, getBrokerDetails tlsConfig write, and Test_Retry message setup

1 participant