Skip to content

fix(remoting): clean up pendingResponses on error paths to prevent map leak#3440

Open
Aias00 wants to merge 3 commits into
apache:developfrom
Aias00:worktree-fix-pending-response-leak
Open

fix(remoting): clean up pendingResponses on error paths to prevent map leak#3440
Aias00 wants to merge 3 commits into
apache:developfrom
Aias00:worktree-fix-pending-response-leak

Conversation

@Aias00

@Aias00 Aias00 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Problem

The global pendingResponses sync.Map is cleaned up on the success path via Response.Handle()removePendingResponse(), but entries were never removed when requests fail. In network failure or timeout scenarios, this map grows indefinitely.

Leak Points

Location Trigger
ExchangeClient.Request() L134 client.Request() returns error
ExchangeClient.AsyncRequest() L168 client.Request() returns error
getty heartbeat() L356 heartbeat timeout (<-gxtime.After(timeout))

Fix

  1. remoting/exchange.go — Export RemovePendingResponse() so external packages (e.g., getty) can call it.
  2. remoting/exchange_client.go — Add removePendingResponse() calls in Request() and AsyncRequest() error paths before returning.
  3. remoting/getty/listener.go — Add remoting.RemovePendingResponse() call in heartbeat() timeout branch to clean up the orphaned entry.

Testing

All remoting/... package tests pass.

🤖 Generated with Claude Code

…p leak

The global pendingResponses sync.Map is cleaned up on the success path
via Response.Handle() -> removePendingResponse(), but entries were never
removed when requests fail:

- ExchangeClient.Request(): AddPendingResponse called before
  client.Request(), but on error the entry was left in the map
- ExchangeClient.AsyncRequest(): same pattern, same leak
- getty heartbeat(): timeout branch never called removePendingResponse,
  leaving the entry to accumulate indefinitely

Add removePendingResponse calls in all three error/timeout paths. Export
RemovePendingResponse so the getty package (external to remoting) can
call it from its heartbeat timeout handler.
Copilot AI review requested due to automatic review settings June 17, 2026 07:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR ensures pending remoting responses are cleaned up when requests time out or fail, preventing stale entries from lingering in the pending response map.

Changes:

  • Remove pending responses on heartbeat read timeout in the Getty listener.
  • Remove pending responses when ExchangeClient request/async-request fails immediately.
  • Export RemovePendingResponse to allow subpackages (e.g., remoting/getty) to trigger cleanup.

Reviewed changes

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

File Description
remoting/getty/listener.go Cleans up the pending response entry on heartbeat timeout.
remoting/exchange_client.go Cleans up the pending response entry when request submission returns an error.
remoting/exchange.go Adds an exported pending-response removal wrapper for cross-package use.

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

Comment thread remoting/exchange.go
Comment on lines +187 to +191
// RemovePendingResponse removes and returns the pending response for the given sequence ID.
// It is the exported version of removePendingResponse for use by external packages.
func RemovePendingResponse(seq SequenceType) *PendingResponse {
return removePendingResponse(seq)
}
Comment on lines 355 to +357
case <-gxtime.After(timeout):
err1 = errHeartbeatReadTimeout
remoting.RemovePendingResponse(remoting.SequenceType(req.ID))
@codecov-commenter

codecov-commenter commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.54%. Comparing base (60d1c2a) to head (db51cda).
⚠️ Report is 861 commits behind head on develop.

Files with missing lines Patch % Lines
remoting/exchange.go 0.00% 2 Missing ⚠️
remoting/exchange_client.go 0.00% 2 Missing ⚠️
remoting/getty/listener.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3440      +/-   ##
===========================================
+ Coverage    46.76%   53.54%   +6.78%     
===========================================
  Files          295      493     +198     
  Lines        17172    38395   +21223     
===========================================
+ Hits          8031    20560   +12529     
- Misses        8287    16182    +7895     
- Partials       854     1653     +799     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sonarqubecloud

Copy link
Copy Markdown

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.

3 participants