Skip to content

ZOOKEEPER-5044: NettyServerCnxnFactory.shutdown must explicitly shut down DefaultEventExecutor#2421

Open
asdf2014 wants to merge 1 commit into
apache:masterfrom
asdf2014:ZOOKEEPER-5044
Open

ZOOKEEPER-5044: NettyServerCnxnFactory.shutdown must explicitly shut down DefaultEventExecutor#2421
asdf2014 wants to merge 1 commit into
apache:masterfrom
asdf2014:ZOOKEEPER-5044

Conversation

@asdf2014

@asdf2014 asdf2014 commented Jul 7, 2026

Copy link
Copy Markdown
Member

See https://issues.apache.org/jira/browse/ZOOKEEPER-5044

NettyServerCnxnFactory backs its channel group with a dedicated DefaultEventExecutor created as an anonymous instance, so shutdown() cannot terminate it and its non-daemon thread (defaultEventExecutor-N-1) survives every factory shutdown.

Instead of adding lifecycle management for that executor, this change stops creating it: the channel group is now backed by GlobalEventExecutor.INSTANCE, the executor the ChannelGroup javadoc recommends. Its single shared thread starts on demand and stops itself after one second of idleness, so there is nothing left to shut down.

Notes for reviewers:

  • No new thread kind is introduced: the termination futures of the boss/worker EventLoopGroups are already notified on GlobalEventExecutor on every shutdown (SingleThreadEventExecutor registers them there), so every factory shutdown already spins this thread up today.
  • The group executor is only used to notify DefaultChannelGroupFuture listeners. The only bulk operation on allChannels in the codebase is the close() inside shutdown() itself, so the shared executor receives one or two sub-millisecond notification tasks per shutdown.
  • Verified by temporarily adding a test that starts and shuts down a factory, then asserts no thread named defaultEventExecutor-* survives: it fails on current master (thread leaked) and passes with this change. The test is not included on purpose — with this fix the dedicated executor no longer exists, so there is nothing left to assert against.

…down DefaultEventExecutor

NettyServerCnxnFactory backs its channel group with a dedicated
DefaultEventExecutor created as an anonymous instance, so shutdown()
cannot terminate it and its non-daemon thread survives every factory
shutdown.

Instead of adding lifecycle management for that executor, stop creating
it: back the channel group with GlobalEventExecutor.INSTANCE, the
executor the ChannelGroup javadoc recommends. Its single shared thread
starts on demand and stops itself after one second of idleness, so
there is nothing left to shut down. This introduces no new thread kind:
the termination futures of the boss/worker EventLoopGroups are already
notified on GlobalEventExecutor on every shutdown.
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.

1 participant