-
Notifications
You must be signed in to change notification settings - Fork 620
wait until processImpl completes before closing stream chan #1677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
wait until processImpl completes before closing stream chan #1677
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes a race condition in query processing where the stream channel could be closed while a background goroutine was still attempting to write to it, causing a panic.
- Adds synchronization to wait for background goroutine completion before returning from
process()function when context is cancelled - Prevents "send on closed channel" panic during query cancellation
- Ensures proper cleanup and resource management without breaking API changes
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| // Wait for goroutine to finish before returning | ||
| select { | ||
| case <-errCh: | ||
| case <-doneCh: | ||
| } |
Copilot
AI
Oct 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'untill' to 'until' in the PR title.
|
@nmerkulov thanks for the PR :) do you mind adding a test case to lock the behavior? |
<ClickHouse/clickhouse-go#1677> UPD исправил фикс на надежный. теперь канал не будет закрыт, пока горутина-писатель не завершится Семантически так правильней commit_hash:ef4786541bee52c63054552b0c593ce70fc6c75b
Fix race condition in query processing
Problem
There was a race condition between closing the
streamchannel and writing to it from a background goroutine inconn_query.go.Race condition scenario:
conn_query.gostarts a goroutine that callsc.process(ctx, onProcess)(line 45)c.process()spawns another goroutine internally that callsc.processImpl()(line 106 inconn_process.go)c.processImpl()reads data from the server and callson.data(block)for each data block (line 170 inconn_process.go)c.process()returns withctx.Err()conn_query.goimmediately closes thestreamchannel (line 54)streamviaon.data(block)panic: send on closed channelStack trace example:
Solution
Modified
conn_process.goto ensure that theprocess()function waits for the internal goroutine to complete before returning, even when the context is cancelled.Changes:
ctx.Done()is triggered, after callingc.cancel(), we now wait for the goroutine to finish by selecting onerrChordoneChon.datawill not be called afterprocess()returnsstreamchannel can now be safely closed inconn_query.gowithout race conditionsImpact