nick-boss-tech opened a new pull request, #5101: URL: https://github.com/apache/solr/pull/5101
🤖 *AI text below* 🤖 *(posted on behalf of Nick Shanin)* https://issues.apache.org/jira/browse/SOLR-18531 ## What happens today A test node that is stopped and then started again on the same port can fail to start. `JettySolrRunner` gives up its port when it stops and holds nothing in its place. If another process takes that port during the gap, the restart fails with `java.net.BindException: Address already in use`. The retry only tries the same port, and it stops after 60 seconds. `LeaderElectionIntegrationTest.testSimpleSliceLeaderElection` hit this once in CI, on an unrelated pull request. No assertion ran. ## What this change does When a runner stops, it binds a socket to its port on 127.0.0.1 and keeps it. The next start on that port closes the socket before Jetty binds the port. The sockets live in a static map, so a new runner for the same port sees them. `MiniSolrCloudCluster.shutdown()` closes the sockets for the runners still in its list after the stops finish, and a runner's `close()` releases its own socket. This is a test-framework change only. Behavior changes: a stopped runner keeps its port bound, so nothing else can bind that port until the node starts on it again or the cluster shuts down. ## Proof New test: `TestJettySolrRunner.testStoppedRunnerKeepsItsPortUntilRestart`. With the two framework source files reverted to the base commit and the new tests kept, it fails on the reservation check: a foreign socket binds the port that a stopped runner released. At this head, `TestJettySolrRunner` passes 3 of 3, including the release on `close()`. Verified 2026-10-10 at 5ba914ca745933251958412a4ccb226ecbaf0ad8. Restart regression runs at the same head, CI seed 3E3D9FF553211ED6: - `LeaderElectionIntegrationTest`: 1 test passes. - `TestCoordinatorRole`: 9 tests pass. - `TestPullReplica`: 39 tests, 1 skipped, 0 failures, run with nightly tests enabled (the class is marked `@Nightly`, so a plain run skips it; the one skip is an `@Ignore`d method). On Linux, a variant of the new test that serves a real request before the stop was also run (two seeds): the port stayed reserved, outside binds were refused even with address reuse allowed, and the restart on the same port worked both times. These runs show that the existing restart tests still pass. They do not show that the flake is gone. It was seen once, so one passing run says little about it. ## A choice to check Two routes. This change holds the port in the framework, so restarts keep the same port, node names and test code. Or the one affected test could restart its node on a fresh port. That needs no reservation, but node names then change with the port, and the test compares node names. The cost of this change is one bound socket per stopped node. Was holding the port the right call? ## Limits - Runners with a socket proxy in front reserve only their Jetty port. The shared cloud test base uses such runners. The proxy port closes on stop and rebinds on start, with no reservation. A failed rebind is logged at debug level and not raised. - A runner stopped with `stopJettySolrRunner` and never restarted is removed from the cluster's list, so cluster shutdown does not release its port. Closing the runner releases it; a runner that is neither restarted nor closed keeps its port until the JVM exits. - A restart on a fresh port leaves the old port reserved the same way, until the old runner is closed or the JVM exits. - Standalone runners that are stopped and never restarted also keep their port until the JVM exits. Changelog: `changelog/unreleased/SOLR-18531-jetty-runner-port-reservation.yml` ### AI assistance AI agents assisted with research, implementation, review, and drafting. Nick Shanin directed the work and takes responsibility for this contribution. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
