Skip to content

fix: prevent sendRequest double-done panic#1501

Open
nodece wants to merge 3 commits into
apache:masterfrom
nodece:fix-sendrequest-done-idempotent
Open

fix: prevent sendRequest double-done panic#1501
nodece wants to merge 3 commits into
apache:masterfrom
nodece:fix-sendrequest-done-idempotent

Conversation

@nodece
Copy link
Copy Markdown
Member

@nodece nodece commented May 20, 2026

Fix #1497

Motivation

Under timeout/reconnect races, the same sendRequest can hit done() more than once from different paths. Since done() clears and returns the object to sendRequestPool, a later duplicate call can access cleared fields and panic with nil pointer dereference.

Modifications

  • Add an idempotency guard (doneFlag) in sendRequest.done() so duplicate invocations on the same instance return immediately.
  • Keep the guard raised after reset/put to block stale-pointer calls in the reset-to-reinit window.
  • Introduce newSendRequest(...) and newChunkSendRequest(...) helpers and route request creation through them, centralizing initialization for pooled objects.
  • Update tests to use constructor helpers where sendRequest is created in tests.
  • Add unit test TestSendRequestDoneIsIdempotentAfterPutToPool to verify a second done() call on the same pointer does not panic after pool return.

nodece and others added 2 commits May 20, 2026 15:31
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 addresses a panic in sendRequest.done() caused by double-invocation under timeout/reconnect races by adding an idempotency guard and centralizing initialization of pooled sendRequest objects.

Changes:

  • Add doneFlag to sendRequest and guard done() with an atomic CAS to make repeated calls a no-op.
  • Introduce newSendRequest(...) / newChunkSendRequest(...) helpers and route pooled object creation through them.
  • Add/adjust tests to validate done() idempotency behavior and use the new constructors.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
pulsar/producer_partition.go Adds doneFlag, constructors for pooled sendRequest, and updates send paths to use them.
pulsar/send_request_pool_test.go Adds a unit test asserting done() can be called twice on the same pointer without panicking after pool return.
pulsar/message_chunking_test.go Updates chunking test helper to construct sendRequest via newSendRequest instead of a literal struct.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pulsar/producer_partition.go Outdated
Comment thread pulsar/producer_partition.go Outdated
Comment thread pulsar/producer_partition.go Outdated
@RobertIndie
Copy link
Copy Markdown
Member

Could you help take a look the comments from Copilot? @nodece

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@nodece
Copy link
Copy Markdown
Member Author

nodece commented Jun 2, 2026

@RobertIndie Done.

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.

Nil pointer panic in sendRequest.done() during producer reconnection via FailTimeoutMessages

3 participants