Skip to content

1fix: prevent duplicate TCP bootstrap server creation - #7012

Open
lymerin wants to merge 1 commit into
apache:masterfrom
lymerin:fix/6735-tcp-bootstrap-race
Open

1fix: prevent duplicate TCP bootstrap server creation#7012
lymerin wants to merge 1 commit into
apache:masterfrom
lymerin:fix/6735-tcp-bootstrap-race

Conversation

@lymerin

@lymerin lymerin commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #6735.

What is changed

TcpProxySelectorDataHandler previously used a non-atomic check-then-act sequence:

inCache -> createBootstrapServer -> cache

Concurrent selector synchronization events could both observe a cache miss and start bootstrap servers for the same selector. This could cause port binding failures or leave an overwritten server and its event-loop resources without lifecycle management.

This change:

  • adds per-selector single-flight creation in TcpBootstrapFactory;
  • ensures concurrent creation requests for the same selector wait for one in-flight creation;
  • performs server startup outside ConcurrentHashMap atomic callbacks and without a global lifecycle lock;
  • allows different selectors to be created and removed independently;
  • uses putIfAbsent when publishing the started server and shuts down a losing instance if another server was already cached;
  • routes TcpProxySelectorDataHandler through the atomic creation and removal methods;
  • preserves the existing public factory methods for compatibility;
  • rolls back LoopResources when bootstrap startup fails;
  • makes TcpBootstrapServer.shutdown() idempotent and preserves shutdown failures using suppressed exceptions.

The change is limited to the duplicate bootstrap creation and related resource lifecycle described in #6735. Existing selector configuration update behavior is unchanged.

Tests

Added or extended tests covering:

  • concurrent creation of the same selector creates only one server;
  • a failed creation can be retried;
  • waiting callers receive the original creation failure;
  • slow shutdown of one selector does not block removal of another selector;
  • bootstrap startup failure disposes its loop resources;
  • repeated shutdown is idempotent;
  • failures from both server and loop-resource disposal are preserved.

The following targeted Maven build passed locally:

mvn -pl shenyu-protocol/shenyu-protocol-tcp,shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-tcp \
    -am \
    -Dtest=TcpBootstrapFactoryTest,TcpBootstrapServerTest,TcpProxySelectorDataHandlerTest \
    -Dsurefire.failIfNoSpecifiedTests=false \
    test

Results:

  • TcpBootstrapServerTest: 11 tests passed
  • TcpBootstrapFactoryTest: 4 tests passed
  • TcpProxySelectorDataHandlerTest: 3 tests passed
  • Checkstyle: no violations

Checklist

@lymerin lymerin closed this Aug 31, 2026
@lymerin lymerin reopened this Aug 31, 2026
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] TcpProxySelectorDataHandler has a TOCTOU race creating duplicate/leaked bootstrap servers

1 participant