@@ -145,6 +145,8 @@ public class Client implements AutoCloseable {
145145 private static final Logger LOG = LoggerFactory .getLogger (Client .class );
146146 private final ExecutorService sharedOperationExecutor ;
147147
148+ private final boolean isSharedOpExecuterorOwned ;
149+
148150 private final Map <String , ClientStatisticsHolder > globalClientStats = new ConcurrentHashMap <>();
149151
150152 private boolean useNewImplementation = false ;
@@ -172,8 +174,10 @@ private Client(Set<String> endpoints, Map<String,String> configuration, boolean
172174
173175 boolean isAsyncEnabled = MapUtils .getFlag (this .configuration , ClientConfigProperties .ASYNC_OPERATIONS .getKey (), false );
174176 if (isAsyncEnabled && sharedOperationExecutor == null ) {
177+ this .isSharedOpExecuterorOwned = true ;
175178 this .sharedOperationExecutor = Executors .newCachedThreadPool (new DefaultThreadFactory ("chc-operation" ));
176179 } else {
180+ this .isSharedOpExecuterorOwned = false ;
177181 this .sharedOperationExecutor = sharedOperationExecutor ;
178182 }
179183 this .useNewImplementation = useNewImplementation ;
@@ -225,12 +229,16 @@ public String getDefaultDatabase() {
225229 */
226230 @ Override
227231 public void close () {
228- try {
229- if (sharedOperationExecutor != null && !sharedOperationExecutor .isShutdown ()) {
230- this .sharedOperationExecutor .shutdownNow ();
232+ if (isSharedOpExecuterorOwned ) {
233+ try {
234+ if (sharedOperationExecutor != null && !sharedOperationExecutor .isShutdown ()) {
235+ this .sharedOperationExecutor .shutdownNow ();
236+ }
237+ } catch (Exception e ) {
238+ LOG .error ("Failed to close shared operation executor" , e );
231239 }
232- } catch ( Exception e ) {
233- LOG .error ( "Failed to close shared operation executor" , e );
240+ } else {
241+ LOG .debug ( "Skip closing operation executor because not owned by client" );
234242 }
235243
236244 if (oldClient != null ) {
@@ -777,9 +785,10 @@ public Builder useAsyncRequests(boolean async) {
777785 /**
778786 * Sets an executor for running operations. If async operations are enabled and no executor is specified
779787 * client will create a default executor.
780- *
788+ * Executor will stay running after {@code Client#close() } is called. It is application responsibility to close
789+ * the executor.
781790 * @param executorService - executor service for async operations
782- * @return
791+ * @return
783792 */
784793 public Builder setSharedOperationExecutor (ExecutorService executorService ) {
785794 this .sharedOperationExecutor = executorService ;
0 commit comments