Skip to content

Conversation

fapifta
Copy link

@fapifta fapifta commented Sep 8, 2025

CURATOR-495 introduced a new runSafeService field in CuratorFrameworkImpl class, and this field is either initialized by an external ExecutorService via the builder, or it is created internally within the class.

In the CuratorFrameworkImpl#close method though, this Executor is never closed, so the threads that are opened by the instances are lingering there until the VM is closed by default. Worse, if someone specifies a thread factory to the framework implementation via the builder that produces non-daemon threads, the VM never exits due to the unstopped single thread executor.

CURATOR-495 introduced a new runSafeService field in CuratorFrameworkImpl class, and this field is
either initialized by an external ExecutorService via the builder, or it is created internally
within the class.

In the CuratorFrameworkImpl#close method though, this Executor is never closed, so the threads
that are opened by the instances are lingering there until the VM is closed by default.
Worse, if someone specifies a thread factory to the framework implementation via the builder that
produces non-daemon threads, the VM never exits due to the unstopped single thread executor.
Copy link
Member

@kezhuw kezhuw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I think we should add javadoc for runSafeService to point out that it is caller's responsibility to shutdown given executor.

if (!isExternalRunSafeService) {
((ExecutorService) runSafeService).shutdownNow();
try {
((ExecutorService) runSafeService).awaitTermination(maxCloseWaitMs, TimeUnit.MILLISECONDS);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have two maxCloseWaitMs now. I am ok for it to be this for now, we can improve it in separated pr.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right, I have changed the approach to ensure we have wait until maxCloseWaitMs for both executor in parallel. Should I add a test for that also what do you think?

@fapifta
Copy link
Author

fapifta commented Sep 9, 2025

@kezhuw Thank you for your review, I added to the JavaDoc of the Builder#runSafeService method, and changed the approach the close waits for these executors to be closed.
I hope the tests now will go through, my understanding is that the failure was not related to the change, but let's see.

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.

2 participants