[cleanup][test] Remove PortManager and use kernel-assigned ports everywhere#25694
Open
merlimat wants to merge 3 commits intoapache:masterfrom
Open
[cleanup][test] Remove PortManager and use kernel-assigned ports everywhere#25694merlimat wants to merge 3 commits intoapache:masterfrom
merlimat wants to merge 3 commits intoapache:masterfrom
Conversation
…ywhere `PortManager` (in pulsar-common) and the inner `BasePortManager` of `LocalBookkeeperEnsemble` allocated "free" ports via `ServerSocket(0)` and tracked them in a JVM-level lock set. The lock was JVM-only, so the OS-level port could still be grabbed by another process between allocation and bind, producing flaky `BindException`s in tests. The class has outlived its usefulness — modern BookKeeper identifies bookies by `bookieId`, not host:port, so port 0 (kernel-assigned) is fine across the board. Removed: - `pulsar-common/...PortManager.java` and its test. - `pulsar-package-management/...test/PortManager.java` (unused duplicate). - `BasePortManager` inner class in `LocalBookkeeperEnsemble`. - `bkBasePort` constructor variants of `LocalBookkeeperEnsemble` (no callers left after the standalone change). - `--bookkeeper-port` CLI option from `PulsarStandalone` (and its setter, getter, builder method, plus 3 test calls). Multi-bookie standalone now always uses kernel-assigned ports — bookies are identified by `bookieId`. - `useDynamicBrokerPorts()` toggle in `MultiBrokerBaseTest` (now always true in spirit; ports come from `getBrokerListenPort()` after start). - `bkPort` field in `BKCluster.BKClusterConf`. Refactored: - `BKCluster`: bookies bind to port 0; `bookieId` is derived from the data dir hash so multiple cluster instances on a shared metadata store don't collide on cookie validation, while restarts on the same dir keep cookies stable. The unused cookie-parsing port-recovery logic is dropped. - `MultiBrokerBaseTest`: `mainBrokerPort` and `additionalBrokerPorts` are populated post-start from `pulsar.getBrokerListenPort()` instead of pre-allocated. - `PulsarTestContext.handlePreallocatePorts`: inlined `ServerSocket(0)` allocation. Still needed by tests that build advertised-listener URLs before the broker starts. - 17 test files: `PortManager.nextLockedFreePort()` calls replaced with `0` (let kernel pick) or inline `ServerSocket(0)` (only where pre-allocation is genuinely needed, e.g. for advertised-listener URLs). - `PulsarStandaloneTest.testStandaloneWithRocksDB`: assertion switched from `getBookiePort()` (now returns kernel-assigned ports that change per restart) to `getBookieId()` (the persistent identity). Behavior change: `--bookkeeper-port` is gone from `pulsar standalone`. Bookies get kernel-assigned ports — no impact for normal usage since clients only connect to the broker.
Now that all callers pass () -> 0, the supplier is dead weight. Remove it from LocalBookkeeperEnsemble entirely; bookies always bind to port 0. Updated all 41 call sites accordingly.
dao-jun
approved these changes
May 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
PortManager(inpulsar-common) and the innerBasePortManagerofLocalBookkeeperEnsembleallocated "free" ports viaServerSocket(0)and tracked them in a JVM-level lock set. The lock was JVM-only, so the OS-level port could still be grabbed by another process between allocation and bind, producing flakyBindExceptions in tests (most recentlyShadowTopicRealBkTest.setup).The class has outlived its usefulness — modern BookKeeper identifies bookies by
bookieId, not host:port, so kernel-assigned ports (port 0) work across the board. The "lock" never actually prevented OS-level collisions anyway.Modifications
Removed
pulsar-common/.../PortManager.javaand its test.pulsar-package-management/.../test/PortManager.java(unused duplicate).BasePortManagerinner class inLocalBookkeeperEnsemble.bkBasePortconstructor variants ofLocalBookkeeperEnsemble.Supplier<Integer> portManagerparameter fromLocalBookkeeperEnsemble— every caller was passing() -> 0. Bookies now always bind to kernel-assigned ports internally.--bookkeeper-portCLI option frompulsar standalone(and its setter, getter, builder method, plus the test calls). Multi-bookie standalone gets kernel-assigned ports.useDynamicBrokerPorts()toggle inMultiBrokerBaseTest(now always dynamic).bkPortfield inBKCluster.BKClusterConf.Refactored
BKCluster: bookies bind to port 0;bookieIdis derived from the data dir hash so multiple cluster instances on a shared metadata store don't collide on cookie validation, while restarts on the same dir keep cookies stable. The unused cookie-parsing port-recovery logic is dropped.MultiBrokerBaseTest:mainBrokerPortandadditionalBrokerPortsare populated post-start frompulsar.getBrokerListenPort()instead of pre-allocated.PulsarTestContext.handlePreallocatePorts: inlinedServerSocket(0)allocation. Still needed by tests that build advertised-listener URLs before the broker starts (those URLs require a known port up front).PortManager.nextLockedFreePort()calls replaced with0(let kernel pick) or inlineServerSocket(0)(only where pre-allocation is genuinely required, e.g. for advertised-listener URLs).PulsarStandaloneTest.testStandaloneWithRocksDB: assertion switched fromgetBookiePort()(now returns kernel-assigned ports that change per restart) togetBookieId()(the persistent BK identity).Behavior change
--bookkeeper-portis gone frompulsar standalone. Bookies get kernel-assigned ports — no impact for normal usage since clients only connect to the broker, not directly to bookies.Verifying this change
Locally exercised the affected tests:
LocalBookkeeperEnsembleTest(2/2)ShadowTopicRealBkTest(1/1)PulsarStandaloneTest(5/5)EndToEndTestforBKCluster(10 passed, 1 skipped)AdvertisedListenersTest,LoadManagerFailFastTest,AdvertisedListenersMultiBrokerLeaderElectionTestFull
compileJavaandcompileTestJavaclean.Does this pull request potentially affect one of the following parts:
--bookkeeper-portCLI option frompulsar standalone--bookkeeper-portremoved frompulsar standalone