Skip to content

fix: initialise BinlogWriter channel before Run() to prevent nil-channel hang#431

Merged
driv3r merged 2 commits intomainfrom
fix-race-condition-between-binlog-streamer-and-buffer
Apr 15, 2026
Merged

fix: initialise BinlogWriter channel before Run() to prevent nil-channel hang#431
driv3r merged 2 commits intomainfrom
fix-race-condition-between-binlog-streamer-and-buffer

Conversation

@driv3r
Copy link
Copy Markdown
Contributor

@driv3r driv3r commented Apr 15, 2026

Ferry.Run() launches BinlogWriter.Run() and BinlogStreamer.Run() in concurrent goroutines (ferry.go:733-745). Previously, the event buffer channel was created inside BinlogWriter.Run(), so if the BinlogStreamer received a row event and called BufferBinlogEvents() before the writer goroutine was scheduled, the send would block forever on a nil channel, hanging the test (observed as TestUpdateBinlogSelectCopy timing out after 10 minutes with goroutine state "chan send (nil chan)").

Introduce BinlogWriter.Initialize() — mirroring the existing pattern on BatchWriter — that allocates the channel and logger eagerly. Call it from Ferry.NewBinlogWriter() so the writer is ready for buffering before any goroutine starts. Add a nil-channel guard in Run() as a defensive fallback for callers that construct BinlogWriter directly.

Add TestBinlogWriterBufferBinlogEventsBeforeRun to give deterministic, sub-second coverage of the race without relying on the slow integration test timeout.

… hang

Ferry.Run() launches BinlogWriter.Run() and BinlogStreamer.Run() in
concurrent goroutines (ferry.go:733-745). Previously, the event buffer
channel was created inside BinlogWriter.Run(), so if the BinlogStreamer
received a row event and called BufferBinlogEvents() before the writer
goroutine was scheduled, the send would block forever on a nil channel,
hanging the test (observed as TestUpdateBinlogSelectCopy timing out after
10 minutes with goroutine state "chan send (nil chan)").

Introduce BinlogWriter.Initialize() — mirroring the existing pattern on
BatchWriter — that allocates the channel and logger eagerly. Call it from
Ferry.NewBinlogWriter() so the writer is ready for buffering before any
goroutine starts. Add a nil-channel guard in Run() as a defensive fallback
for callers that construct BinlogWriter directly.

Add TestBinlogWriterBufferBinlogEventsBeforeRun to give deterministic,
sub-second coverage of the race without relying on the slow integration
test timeout.
@driv3r driv3r requested a review from a team April 15, 2026 08:48
@driv3r driv3r added the Bug Something isn't working label Apr 15, 2026
Base automatically changed from logging-improvements-with-zerolog to main April 15, 2026 11:08
Comment thread binlog_writer.go Outdated
@driv3r driv3r merged commit 26ab10f into main Apr 15, 2026
12 of 13 checks passed
@driv3r driv3r deleted the fix-race-condition-between-binlog-streamer-and-buffer branch April 15, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants