curator icon indicating copy to clipboard operation
curator copied to clipboard

[CURATOR-557] ServiceCacheImpl does not close ExecutorService

Open jira-importer opened this issue 5 years ago • 15 comments

ServiceCacheImpl does not close the ExecutorService instance created from the ThreadFactory:

https://github.com/apache/curator/blob/master/curator-x-discovery/src/main/java/org/apache/curator/x/discovery/details/ServiceCacheImpl.java#L64

 

CloseableExecutorService::CloseableExecutorService(ExecutorService) call this(executorService, false) which sets shutdownOnClose to false.

 

this has an impact from callers, eg ServiceProviderImpl, which only allow only a ThreadFactory to be specified.

 

 


Originally reported by rnaude, imported from: ServiceCacheImpl does not close ExecutorService
  • status: Open
  • priority: Major
  • resolution: Unresolved
  • imported: 2025-01-21

jira-importer avatar Jan 22 '20 11:01 jira-importer

rnaude:

maybe i missed something here:

ServiceCacheImpl(ServiceDiscoveryImpl discovery, String name, ThreadFactory threadFactory) -> convertThreadFactory(threadFactory) -> new CloseableExecutorService(Executors.newSingleThreadExecutor(threadFactory))

 

PathChildrenCache receives the CloseableExecutorService with shutdownOnClose = false, thus not closing the executor?

jira-importer avatar Jan 22 '20 13:01 jira-importer

randgalt:

OK - I'll have a look at that when I get a chance (or another committer can).

jira-importer avatar Jan 22 '20 13:01 jira-importer

rnaude:

have attached a patch:

  • ServiceCacheImpl should tell CloseableExecutorService to close the executor when creating it from ThreadFactory
  • CloseableExecutorService now await the shutdown of the executor
  • expose setting an ExecutorService on ServiceCacheImpl via ServiceProviderBuilder / ServiceProviderImpl

jira-importer avatar Jan 23 '20 07:01 jira-importer

shayshim:

  1. Makes sense, since the CloseableExecutorService that is created there is the exclusive owner of the new ExecutorService.
  2. Might be a good idea, but maybe should allow users to pick their own wait on close time
  3. If it can be useful for you, why not

jira-importer avatar Jan 24 '20 14:01 jira-importer

rnaude:

Shay Shimony:

with regards to the wait on close time. can you propose a solution? it is hidden away from normal use and not easily exposed. not sure if curator provides a global / singleton configuration interface? if so, then it can be added there.

jira-importer avatar Jan 24 '20 14:01 jira-importer

shayshim:

We could introduce new method CloseableExecutorService.awaitTermination or similar that passes through the time to the ExecutorService. So we get similar pattern of usage to the ExecutorService.shutdownNow and awaitTermination. That's just an idea.

We could also pass the termination time through the constructor of CloseableExecutorService. But I like it less.

jira-importer avatar Jan 24 '20 15:01 jira-importer

randgalt:

Sounds like a good idea Shay Shimony

jira-importer avatar Jan 24 '20 17:01 jira-importer

shayshim:

Thinking about it again, it won't be easy to use the CloseableExecutorService.awaitTermination, because it is an internal component of the service provider.
CloseableExecutorService is wrapped by PathChildrenCache which is wrapped by ServiceCacheImpl which is wrapped by ServiceProviderImpl. We would need to add each one of them awaitTermination.

I suggest to leave the CloseableExecutorService.close() method as it is (no call to ExecutorService.awaitTermination from there), and in case that the users want to do ThreadExecutor.awaitTermination then they should create their own ExecutorService and build the ServiceProviderImpl upon it (using your new API in ServiceProviderBuilder). Thus, after calling close() on the service provider the users still have control and can call ExecutorService.shutdownNow and awaitTermination however they want.

In my opinion, the users should use the ThreadFactory only if they don't need to await the termination of threads. If they do need, they still can get back the control as mentioned.

We still need 1 and 3.

jira-importer avatar Jan 26 '20 08:01 jira-importer

randgalt:

Sounds good Shay Shimony. We can even deprecate the troublesome version (threadFactory(ThreadFactory threadFactory)).

jira-importer avatar Jan 26 '20 15:01 jira-importer

shayshim:

OK Jordan Zimmerman.

Roelof Naude, does it make sense to you? Would you open a pull request with the fix or should I?

jira-importer avatar Jan 26 '20 21:01 jira-importer

rnaude:

Shay Shimony sure. can provide a patch.

 

in short:

  1. deprecate use of ThreadFactory
  2. fix close issue
  3. ExecutorService addition to ServiceProvider?

jira-importer avatar Jan 27 '20 06:01 jira-importer

shayshim:

Roelof Naude sounds right, thanks, but don't need new patch. I will create pull request based on your patch later today.

jira-importer avatar Jan 27 '20 06:01 jira-importer