Repository navigation
fix(microservices): retry the tcp server again after close and listen - #18238
Merged
kamilmysliwiec merged 1 commit intoOct 22, 2026
Merged
Conversation
close() turns retries off, and a later listen() never turned them back on, so a ServerTCP instance that was closed and listened again no longer re-listened after an unexpected close. listen() now turns them back on. The close event of the earlier close() can arrive after that listen(); a retry is not armed, or does not listen, while the server is listening, which would throw ERR_SERVER_ALREADY_LISTEN from the retry timer.
4 of 6 tasks
4 of 12 tasks
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.
What is the current behavior?
ServerTCP#close()setsisManuallyTerminated, and nothing ever resets it. If an instance is closed and then listened again,handleClose()returns early forever, so an unexpected close of the server never re-listens, whateverretryAttemptsis set to.I reproduced this on a real socket:
listen(), thenclose(), thenlisten(), thenunwrap<net.Server>().close(). The server stays down.This came up while reviewing #18223, which handles the stale retry timer in the same restart path.
What is the new behavior?
listen()resetsisManuallyTerminated, as it already resets the attempt count and the pending timer.Resetting the flag alone is not enough. A
close()emitscloseonly once its open connections end, and that can be after the followinglisten(). The stale event would then arm a retry that callslistenon a server that is already listening, throwingERR_SERVER_ALREADY_LISTENfrom the timer. The same real-socket probe crashed this way when only the flag was reset. To prevent that:handleClose()doesn't arm a retry while the server is listening.listenonce the server is listening again.With both checks, the probe has three cases, and all three re-listen after the external close without an error:
Tests
Three unit tests:
listen()afterclose()arms a retry again;closeevent while the server is listening;listenonce the server listens again.All three fail on master. The microservices unit suite passes (1382 tests).
Does this PR introduce a breaking change?