Repository navigation
[fix][tableview] Cancel reader context in Close() to prevent potential deadlock - #1558
Conversation
|
@crossoverJie |
|
Could you rebase this onto the current master? @zjxxzjwang |
|
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
1 open issue
What changed in this PR
Fixes a potential deadlock in TableViewImpl.Close() by canceling each reader’s context before closing the reader, and adds a regression test intended to ensure Close() returns promptly.
Changes:
- Cancel each reader’s context (
cancelFunc()) before callingreader.Close()inTableViewImpl.Close(). - Add a unit test that attempts to reproduce and guard against the deadlock scenario.
| File | Description |
|---|---|
| pulsar/table_view_impl.go | Cancels reader contexts prior to closing readers to prevent Next(ctx) from blocking shutdown. |
| pulsar/table_view_test.go | Adds a regression test and a mock reader intended to verify Close() doesn’t deadlock. |
Review effort: Lite
# Conflicts: # pulsar/table_view_test.go
|
@crossoverJie Hello, I have modified the test cases based on the feedback. Please review. |

Motivation
TableViewImpl.Close()iterates over all registeredcancelReadersand callsreader.Close()for each one, but it never callscancelFunc()to cancelthe context passed to
watchReaderForNewMessages.Each
watchReaderForNewMessagesgoroutine blocks onreader.Next(ctx).Internally,
reader.Close()callsconsumer.closeWithCause()which invokeswg.Wait()to wait for all partition consumer goroutines to finish. However,because the context is never cancelled,
reader.Next(ctx)may remain blockedindefinitely — the goroutine cannot exit,
wg.Wait()never completes, andClose()hangs while holdingreadersMu. This is a deadlock.Note that
partitionUpdateCheck()already handles this correctly when removingstale partitions — it calls
cancelFunc()beforereader.Close(). TheClose()method was simply missing the same treatment.
Modifications
cancelReader.cancelFunc()beforecancelReader.reader.Close()inTableViewImpl.Close(), consistent with the pattern inpartitionUpdateCheck().Verifying this change
This change added tests and can be verified as follows:
TestCloseCallsCancelFuncToAvoidDeadlock: creates aTableViewImplwitha mock reader whose
Next()blocks onctx.Done(), starts a watcher goroutine,then calls
Close()and asserts it returns within 3 seconds. Without the fix,Close()deadlocks and the test times out.Does this pull request potentially affect one of the following parts:
Documentation
This is a bug fix for an internal deadlock, no user-facing feature is added.