Skip to content

Conversation

@dgageot
Copy link
Member

@dgageot dgageot commented Jan 7, 2026

Detected with:

go test --count=1 -race ./...

Add proper synchronization for global telemetry variables and Client.version
field to prevent races between:
- SetGlobalTelemetryVersion writing globalTelemetryVersion
- EnsureGlobalTelemetryInitialized reading globalTelemetryVersion
- SetGlobalTelemetryVersion writing Client.version
- performHTTPRequest and createEvent reading Client.version

Changes:
- Add globalMu RWMutex to protect globalTelemetryVersion and globalTelemetryDebugMode
- Add setVersion/getVersion methods to Client for thread-safe version access
- Pass version as parameter to performHTTPRequest to avoid deadlock

Assisted-By: cagent
Add mutex synchronization to mockSource struct to prevent races between:
- Test goroutine modifying data/err fields
- Background refresh goroutine reading data/err fields

Added thread-safe accessor methods:
- setData() for updating mock data
- setErr() for updating mock error
- getReadCount() for reading call count

Assisted-By: cagent
Add mutex synchronization to queueProvider.CreateChatCompletionStream to
prevent races when multiple goroutines access the streams slice.

Use index-based tracking instead of slice mutation for thread safety.

Assisted-By: cagent
Add RWMutex synchronization to Session struct to prevent races between:
- AddMessage writing to Messages slice
- GetAllMessages reading from Messages slice
- GetMessages reading from Messages slice

This race was detected when the title generator goroutine calls
GetLastUserMessageContent() while the main runtime loop is adding messages.

Changes:
- Add mu sync.RWMutex field to Session struct
- Protect AddMessage and AddSubSession with Lock()
- Protect GetAllMessages with RLock()
- Protect s.Messages access in GetMessages with RLock()

Assisted-By: cagent
@dgageot dgageot requested a review from a team as a code owner January 7, 2026 16:48
}

// getAllMessagesLocked extracts all messages without acquiring the lock (caller must hold lock)
func (s *Session) getAllMessagesLocked() []Message {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are there any scenarios where we want to call this func without the caller having acquired the lock beforehand?

@dgageot dgageot closed this Jan 8, 2026
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.

2 participants