coordinator: avoid cdc hang on recvMessages (#4441)#5241
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request changes the message sending behavior in coordinator.go from non-blocking to blocking by removing the default case in the select statement. Feedback highlights a potential deadlock during shutdown or error handling, where a sender could block indefinitely on c.eventCh.In() while Stop() waits for the wait group. To resolve this, the reviewer suggests introducing a stopCh to signal cancellation to blocked senders.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| select { | ||
| case <-ctx.Done(): | ||
| return context.Cause(ctx) | ||
| default: | ||
| c.eventCh.In() <- &Event{message: msg} | ||
| case c.eventCh.In() <- &Event{message: msg}: | ||
| } |
There was a problem hiding this comment.
Potential Deadlock during Shutdown / Error Handling
There is a potential deadlock scenario when a goroutine in the errgroup fails or during coordinator shutdown:
- Goroutine Failure: If any goroutine in the
errgroup(e.g.,run,gcCleaner.Run) fails, theerrgroupcontext is canceled, causingrunHandleEventto exit. - No Reader: Once
runHandleEventexits, nothing is reading fromc.eventCh.Out(). - Blocked Sender: If a new message arrives before
Stop()is called,recvMessagespasses thec.closedcheck and blocks onc.eventCh.In() <- .... - Deadlock in
Stop(): WhenStop()is eventually called, it executesc.msgGuardWaitGroup.Wait()before canceling the context or closing the channel. SincerecvMessagesis blocked on the channel send, it never callsDone(), causingStop()to hang indefinitely.
Recommended Solution
Introduce a stopCh chan struct{} to signal cancellation to blocked senders:
- Add
stopCh chan struct{}to thecoordinatorstruct. - Initialize it in
New:stopCh: make(chan struct{}). - Close it in
Stop()before waiting on the wait group:close(c.stopCh) c.msgGuardWaitGroup.Wait()
- Select on
c.stopChinrecvMessagesas shown in the suggestion.
| select { | |
| case <-ctx.Done(): | |
| return context.Cause(ctx) | |
| default: | |
| c.eventCh.In() <- &Event{message: msg} | |
| case c.eventCh.In() <- &Event{message: msg}: | |
| } | |
| select { | |
| case <-ctx.Done(): | |
| return context.Cause(ctx) | |
| case <-c.stopCh: | |
| return errors.New("coordinator stopped") | |
| case c.eventCh.In() <- &Event{message: msg}: | |
| } |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: wk989898 The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
This is an automated cherry-pick of #4441
What problem does this PR solve?
Issue Number: close #4440
What is changed and how it works?
Coordinator Message Handling: Modified the recvMessages function in the coordinator to prevent potential hangs. The change involves updating the select statement to directly attempt sending messages to the eventCh rather than using a default case, ensuring proper synchronization and avoiding blocking.
Check List
Tests
Questions
Will it cause performance regression or break compatibility?
Do you need to update user documentation, design documentation or monitoring documentation?
Release note
Summary by CodeRabbit