Skip to content

fix(tcp): unregister ActivityConnectionObserver on connection dispose to prevent memory leak - #6453

Open
wy471x wants to merge 1 commit into
apache:masterfrom
wy471x:fix_TCP-proxy-leaks-per-connection
Open

fix(tcp): unregister ActivityConnectionObserver on connection dispose to prevent memory leak#6453
wy471x wants to merge 1 commit into
apache:masterfrom
wy471x:fix_TCP-proxy-leaks-per-connection

Conversation

@wy471x

@wy471x wy471x commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Per-connection observers were registered on the shared EventBus but never
unregistered, causing stale observers to accumulate. Added onDispose cleanup
and error handling for failed downstream connections.

Per-connection observers were registered on the shared EventBus but never unregistered, causing stale observers to accumulate. Added onDispose cleanup and error handling for failed downstream connections.

Make sure that:

  • You have read the contribution guidelines.
  • You submit test cases (unit or integration tests) that back your changes.
  • Your local test passed ./mvnw clean install -Dmaven.javadoc.skip=true.

Summary of Changes

Problem

Every inbound TCP connection in TcpBootstrapServer.bridgeConnections() created a new
ActivityConnectionObserver and registered it on the shared EventBus, but never unregistered it.
This caused:

  1. Memory leak — dead observers accumulated in the EventBus, each holding stale Connection
    references in their cache map
  2. Fan-out waste — each removeCommonUpstream() event was posted to every observer ever created,
    not just active ones
  3. Orphaned connections — when the downstream client connection failed, the serverConn was
    never disposed and no error was logged

Fix (TcpBootstrapServer.java)

Two changes in bridgeConnections():

  1. serverConn.onDispose(() -> eventBus.unregister(connectionObserver)) — ensures the observer
    is unregistered from the EventBus when the connection terminates
  2. Error handler on client.subscribe() — on failure, immediately unregisters the observer,
    disposes the server connection, and logs the error

Tests (TcpBootstrapServerTest.java — new file)

4 unit tests covering the lifecycle:

Test: shouldUnregisterObserverWhenServerConnectionIsDisposed
What it verifies: Observer is unregistered when the server connection disposes
────────────────────────────────────────
Test: shouldUnregisterObserverAndDisposeServerConnOnClientConnectionError
What it verifies: On client connection failure, observer is unregistered and serverConn is
disposed
────────────────────────────────────────
Test: shouldBridgeConnectionsOnSuccessfulClientConnection
What it verifies: On success, bridge.bridge() is called with correct connections
────────────────────────────────────────
Test: shouldUseSameObserverForEventBusAndConnectionContext
What it verifies: The same observer instance is used for both EventBus registration and
connection observation

close #6448

… to prevent memory leak

Per-connection observers were registered on the shared EventBus but never
unregistered, causing stale observers to accumulate. Added onDispose cleanup
and error handling for failed downstream connections.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

[BUG] TCP proxy leaks per-connection EventBus observers

1 participant