You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/08/31 07:16:25 UTC

[isis] branch master updated (da07f5d -> f8f3b56)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git.


    from da07f5d  Merge remote-tracking branch 'apache/maint-2.0.0-M1'
     new 539e004  ISIS-1974: (porting from 1.16.x)  support sequential execution
     new fe8542e  ISIS-1841: Internal API: add a thread-safe variant of _Lacy
     new f8f3b56  ISIS-1974: (porting from maint-1.16.2)

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/isis/commons/internal/base/_Lazy.java   |  8 ++-
 .../base/{_Lazy.java => _LazyThreadSafe.java}      | 37 +++++++----
 .../core/runtime/threadpool/ThreadPoolSupport.java | 69 +++++++++++++++++----
 .../plugins/jdo/dn4/IsisJdoSupportPlugin4.java     |  5 +-
 .../DataNucleusApplicationComponents4.java         | 38 +++++-------
 .../persistence/PersistenceSessionFactory4.java    | 47 ++++++++------
 .../plugins/jdo/dn5/IsisJdoSupportPlugin5.java     |  5 +-
 .../DataNucleusApplicationComponents5.java         | 15 +----
 .../persistence/PersistenceSessionFactory5.java    | 47 ++++++++------
 .../isis/core/metamodel/IsisJdoRuntimePlugin.java  |  3 +-
 .../persistence/PersistenceSessionFactory.java     |  9 ++-
 .../system/session/IsisSessionFactoryBuilder.java  | 71 +++++++++++++---------
 .../objectstore/jdo/service/RegisterEntities.java  | 27 ++++----
 13 files changed, 221 insertions(+), 160 deletions(-)
 copy core/commons/src/main/java/org/apache/isis/commons/internal/base/{_Lazy.java => _LazyThreadSafe.java} (65%)


[isis] 02/03: ISIS-1841: Internal API: add a thread-safe variant of _Lacy

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit fe8542e765afc05ef3e5d1210c0b8afeb732a91c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Aug 31 08:55:01 2018 +0200

    ISIS-1841: Internal API: add a thread-safe variant of _Lacy
---
 .../apache/isis/commons/internal/base/_Lazy.java   |  8 ++++-
 .../base/{_Lazy.java => _LazyThreadSafe.java}      | 37 +++++++++++++++-------
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
index f3ba221..18eb150 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
@@ -26,7 +26,7 @@ import java.util.function.Supplier;
 /**
  * <h1>- internal use only -</h1>
  * <p>
- * Supplier with memoization.
+ * (non-thread-safe) Supplier with memoization.
  * </p>
  * <p>
  * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
@@ -41,6 +41,12 @@ public final class _Lazy<T> implements Supplier<T> {
     private T value;
     private boolean memoized;
 
+    /**
+     * Concurrent calls to this lazy's get() method might result in concurrent calls to the 
+     * specified {@code supplier}. 
+     * @param supplier
+     * @return an (non-thread-safe) instance of _Lacy that initializes with the specified {@code supplier}
+     */
     public static <T> _Lazy<T> of(Supplier<? extends T> supplier) {
         return new _Lazy<T>(supplier);
     }
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_LazyThreadSafe.java
similarity index 65%
copy from core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
copy to core/commons/src/main/java/org/apache/isis/commons/internal/base/_LazyThreadSafe.java
index f3ba221..436cd36 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/base/_Lazy.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/base/_LazyThreadSafe.java
@@ -26,7 +26,7 @@ import java.util.function.Supplier;
 /**
  * <h1>- internal use only -</h1>
  * <p>
- * Supplier with memoization.
+ * Thread-safe Supplier with memoization.
  * </p>
  * <p>
  * <b>WARNING</b>: Do <b>NOT</b> use any of the classes provided by this package! <br/>
@@ -35,17 +35,24 @@ import java.util.function.Supplier;
  *
  * @since 2.0.0
  */
-public final class _Lazy<T> implements Supplier<T> {
+public final class _LazyThreadSafe<T> implements Supplier<T> {
 
     private final Supplier<? extends T> supplier;
     private T value;
     private boolean memoized;
 
-    public static <T> _Lazy<T> of(Supplier<? extends T> supplier) {
-        return new _Lazy<T>(supplier);
+    /**
+     * Thread-safe variant to {@link _Lazy#of(Supplier)}.
+     * Concurrent calls to this lazy's get() method will never result in concurrent calls to the 
+     * specified {@code supplier}. 
+     * @param supplier
+     * @return an (thread-safe) instance of _Lacy that initializes with the specified {@code supplier}
+     */
+    public static <T> _LazyThreadSafe<T> of(Supplier<? extends T> supplier) {
+        return new _LazyThreadSafe<T>(supplier);
     }
 
-    private _Lazy(Supplier<? extends T> supplier) {
+    private _LazyThreadSafe(Supplier<? extends T> supplier) {
         this.supplier = requires(supplier, "supplier");
     }
 
@@ -53,7 +60,9 @@ public final class _Lazy<T> implements Supplier<T> {
      * @return whether this lazy got initialized and holds a memoized value
      */
     public boolean isMemoized() {
-        return memoized;
+        synchronized (this) {
+            return memoized;    
+        }
     }
 
     /**
@@ -62,8 +71,10 @@ public final class _Lazy<T> implements Supplier<T> {
      *
      */
     public void clear() {
-        this.memoized = false;
-        this.value = null;
+        synchronized (this) {
+            this.memoized = false;
+            this.value = null;
+        }
     }
 
     /**
@@ -72,11 +83,13 @@ public final class _Lazy<T> implements Supplier<T> {
      */
     @Override
     public T get() {
-        if(memoized) {
-            return value;
+        synchronized (this) {
+            if(memoized) {
+                return value;
+            }
+            memoized=true;
+            return value = supplier.get();    
         }
-        memoized=true;
-        return value = supplier.get();
     }
 
 }


[isis] 03/03: ISIS-1974: (porting from maint-1.16.2)

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f8f3b56140205cccc75d2a574f23935d31f48c6f
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Aug 31 09:16:17 2018 +0200

    ISIS-1974: (porting from maint-1.16.2)
    
    working towards removing SpecificationLoader
    initializes the Isis metamodel and DN in parallel
---
 .../plugins/jdo/dn4/IsisJdoSupportPlugin4.java     |  5 +-
 .../DataNucleusApplicationComponents4.java         | 38 +++++-------
 .../persistence/PersistenceSessionFactory4.java    | 47 ++++++++------
 .../plugins/jdo/dn5/IsisJdoSupportPlugin5.java     |  5 +-
 .../DataNucleusApplicationComponents5.java         | 15 +----
 .../persistence/PersistenceSessionFactory5.java    | 47 ++++++++------
 .../isis/core/metamodel/IsisJdoRuntimePlugin.java  |  3 +-
 .../persistence/PersistenceSessionFactory.java     |  9 ++-
 .../system/session/IsisSessionFactoryBuilder.java  | 71 +++++++++++++---------
 .../objectstore/jdo/service/RegisterEntities.java  | 27 ++++----
 10 files changed, 133 insertions(+), 134 deletions(-)

diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apacha/isis/plugins/jdo/dn4/IsisJdoSupportPlugin4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apacha/isis/plugins/jdo/dn4/IsisJdoSupportPlugin4.java
index 8470ee7..c1026c8 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apacha/isis/plugins/jdo/dn4/IsisJdoSupportPlugin4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apacha/isis/plugins/jdo/dn4/IsisJdoSupportPlugin4.java
@@ -22,7 +22,6 @@ import javax.annotation.Nullable;
 
 import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
 import org.apache.isis.core.metamodel.IsisJdoRuntimePlugin;
-import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory4;
 
@@ -42,8 +41,8 @@ public class IsisJdoSupportPlugin4 implements IsisJdoMetamodelPlugin, IsisJdoRun
     }
 
     @Override
-    public PersistenceSessionFactory getPersistenceSessionFactory(ConfigurationServiceInternal isisConfiguration) {
-        return new PersistenceSessionFactory4(isisConfiguration);
+    public PersistenceSessionFactory getPersistenceSessionFactory(/*ConfigurationServiceInternal isisConfiguration*/) {
+        return new PersistenceSessionFactory4(/*isisConfiguration*/);
     }
 
 }
diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents4.java
index 8f08291..fbe6318 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents4.java
@@ -25,6 +25,17 @@ import java.util.Set;
 import javax.jdo.JDOHelper;
 import javax.jdo.PersistenceManagerFactory;
 
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+
+import org.datanucleus.PersistenceNucleusContext;
+import org.datanucleus.PropertyNames;
+import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+import org.datanucleus.metadata.MetaDataListener;
+import org.datanucleus.metadata.MetaDataManager;
+import org.datanucleus.store.StoreManager;
+import org.datanucleus.store.schema.SchemaAwareStoreManager;
+
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.factory.InstanceUtil;
@@ -36,16 +47,6 @@ import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusLifeCycleHelper;
 import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware;
 import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoNamedQuery;
 import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryFacet;
-import org.datanucleus.PersistenceNucleusContext;
-import org.datanucleus.PropertyNames;
-import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
-import org.datanucleus.metadata.MetaDataListener;
-import org.datanucleus.metadata.MetaDataManager;
-import org.datanucleus.store.StoreManager;
-import org.datanucleus.store.schema.SchemaAwareStoreManager;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Maps;
 
 public class DataNucleusApplicationComponents4 implements ApplicationScopedComponent {
 
@@ -82,35 +83,25 @@ public class DataNucleusApplicationComponents4 implements ApplicationScopedCompo
 
     private final Set<String> persistableClassNameSet;
     private final IsisConfiguration jdoObjectstoreConfig;
-    private final SpecificationLoader specificationLoader;
     private final Map<String, String> datanucleusProps;
 
-    private Map<String, JdoNamedQuery> namedQueryByName;
     private PersistenceManagerFactory persistenceManagerFactory;
 
     public DataNucleusApplicationComponents4(
             final IsisConfiguration configuration,
-            final SpecificationLoader specificationLoader,
             final Map<String, String> datanucleusProps,
             final Set<String> persistableClassNameSet) {
-        this.specificationLoader = specificationLoader;
 
         this.datanucleusProps = datanucleusProps;
         this.persistableClassNameSet = persistableClassNameSet;
         this.jdoObjectstoreConfig = configuration;
 
-        initialize();
+        persistenceManagerFactory = createPmfAndSchemaIfRequired(this.persistableClassNameSet, this.datanucleusProps);
 
         // for JRebel plugin
         instance = this;
     }
 
-    private void initialize() {
-        persistenceManagerFactory = createPmfAndSchemaIfRequired(persistableClassNameSet, datanucleusProps);
-
-        namedQueryByName = catalogNamedQueries(persistableClassNameSet);
-    }
-
     /**
      * Marks the end of DataNucleus' life-cycle. Purges any state associated with DN.
      * Subsequent calls have no effect.
@@ -251,8 +242,9 @@ public class DataNucleusApplicationComponents4 implements ApplicationScopedCompo
         properties.putAll(props);
         return properties;
     }
-
-    private Map<String, JdoNamedQuery> catalogNamedQueries(Set<String> persistableClassNames) {
+    
+    static Map<String, JdoNamedQuery> catalogNamedQueries(
+            Set<String> persistableClassNames, final SpecificationLoader specificationLoader) {
         final Map<String, JdoNamedQuery> namedQueryByName = Maps.newHashMap();
         for (final String persistableClassName: persistableClassNames) {
             final ObjectSpecification spec = specificationLoader.loadSpecification(persistableClassName);
diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java
index 3e4941a..9c547ae 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java
@@ -24,20 +24,20 @@ import java.util.Set;
 
 import javax.jdo.PersistenceManagerFactory;
 
+import org.datanucleus.PropertyNames;
+import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
 import org.apache.isis.objectstore.jdo.service.RegisterEntities;
-import org.datanucleus.PropertyNames;
-import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  *
@@ -53,11 +53,11 @@ PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstalledFlag {
 
     private static final Logger LOG = LoggerFactory.getLogger(PersistenceSessionFactory4.class);
 
-    private final ConfigurationServiceInternal configuration;
-
-    public PersistenceSessionFactory4(final ConfigurationServiceInternal isisConfiguration) {
-        this.configuration = isisConfiguration;
-    }
+//    private final ConfigurationServiceInternal configuration;
+//
+//    public PersistenceSessionFactory4(final ConfigurationServiceInternal isisConfiguration) {
+//        this.configuration = isisConfiguration;
+//    }
 
     public static final String JDO_OBJECTSTORE_CONFIG_PREFIX = "isis.persistor.datanucleus";  // specific to the JDO objectstore
     public static final String DATANUCLEUS_CONFIG_PREFIX = "isis.persistor.datanucleus.impl"; // reserved for datanucleus' own config props
@@ -67,8 +67,8 @@ PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstalledFlag {
 
     @Programmatic
     @Override
-    public void init(final SpecificationLoader specificationLoader) {
-        this.applicationComponents = createDataNucleusApplicationComponents(configuration, specificationLoader);
+    public void init(final IsisConfigurationDefault configuration) {
+        this.applicationComponents = createDataNucleusApplicationComponents(configuration);
     }
 
     @Programmatic
@@ -78,9 +78,12 @@ PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstalledFlag {
     }
 
     private DataNucleusApplicationComponents4 createDataNucleusApplicationComponents(
-            final IsisConfiguration configuration, final SpecificationLoader specificationLoader) {
+            final IsisConfiguration configuration) {
 
-        if (applicationComponents == null || applicationComponents.isStale()) {
+        final RegisterEntities registerEntities = new RegisterEntities(/*configuration.asMap()*/);
+        final Set<String> classesToBePersisted = registerEntities.getEntityTypes();
+        
+        if (shouldCreate(this.applicationComponents)) {
 
             final IsisConfiguration jdoObjectstoreConfig = configuration.createSubset(
                     JDO_OBJECTSTORE_CONFIG_PREFIX);
@@ -89,15 +92,19 @@ PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstalledFlag {
             final Map<String, String> datanucleusProps = dataNucleusConfig.asMap();
             addDataNucleusPropertiesIfRequired(datanucleusProps);
 
-            final RegisterEntities registerEntities = new RegisterEntities(specificationLoader);
-            final Set<String> classesToBePersisted = registerEntities.getEntityTypes();
-
-            applicationComponents = new DataNucleusApplicationComponents4(jdoObjectstoreConfig, specificationLoader,
-                    datanucleusProps, classesToBePersisted);
+            DataNucleusApplicationComponents4 applicationComponents1 = 
+                    new DataNucleusApplicationComponents4(jdoObjectstoreConfig,
+                            datanucleusProps, classesToBePersisted);
+            
+            this.applicationComponents = applicationComponents1;
         }
 
         return applicationComponents;
     }
+    
+    private boolean shouldCreate(final DataNucleusApplicationComponents4 applicationComponents) {
+        return applicationComponents == null || applicationComponents.isStale();
+    }
 
     private static void addDataNucleusPropertiesIfRequired(
             final Map<String, String> props) {
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apacha/isis/plugins/jdo/dn5/IsisJdoSupportPlugin5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apacha/isis/plugins/jdo/dn5/IsisJdoSupportPlugin5.java
index 94164d0..0db3fee 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apacha/isis/plugins/jdo/dn5/IsisJdoSupportPlugin5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apacha/isis/plugins/jdo/dn5/IsisJdoSupportPlugin5.java
@@ -22,7 +22,6 @@ import javax.annotation.Nullable;
 
 import org.apache.isis.core.metamodel.IsisJdoMetamodelPlugin;
 import org.apache.isis.core.metamodel.IsisJdoRuntimePlugin;
-import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory5;
 
@@ -42,8 +41,8 @@ public class IsisJdoSupportPlugin5 implements IsisJdoMetamodelPlugin, IsisJdoRun
     }
 
     @Override
-    public PersistenceSessionFactory getPersistenceSessionFactory(ConfigurationServiceInternal isisConfiguration) {
-        return new PersistenceSessionFactory5(isisConfiguration);
+    public PersistenceSessionFactory getPersistenceSessionFactory(/*ConfigurationServiceInternal isisConfiguration*/) {
+        return new PersistenceSessionFactory5(/*isisConfiguration*/);
     }
 
 }
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java
index 7b0f1ad..56265dd 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java
@@ -82,35 +82,25 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
 
     private final Set<String> persistableClassNameSet;
     private final IsisConfiguration jdoObjectstoreConfig;
-    private final SpecificationLoader specificationLoader;
     private final Map<String, String> datanucleusProps;
 
-    private Map<String, JdoNamedQuery> namedQueryByName;
     private PersistenceManagerFactory persistenceManagerFactory;
 
     public DataNucleusApplicationComponents5(
             final IsisConfiguration configuration,
-            final SpecificationLoader specificationLoader,
             final Map<String, String> datanucleusProps,
             final Set<String> persistableClassNameSet) {
-        this.specificationLoader = specificationLoader;
 
         this.datanucleusProps = datanucleusProps;
         this.persistableClassNameSet = persistableClassNameSet;
         this.jdoObjectstoreConfig = configuration;
 
-        initialize();
+        persistenceManagerFactory = createPmfAndSchemaIfRequired(this.persistableClassNameSet, this.datanucleusProps);
 
         // for JRebel plugin
         instance = this;
     }
 
-    private void initialize() {
-        persistenceManagerFactory = createPmfAndSchemaIfRequired(persistableClassNameSet, datanucleusProps);
-
-        namedQueryByName = catalogNamedQueries(persistableClassNameSet);
-    }
-
     /**
      * Marks the end of DataNucleus' life-cycle. Purges any state associated with DN.
      * Subsequent calls have no effect.
@@ -252,7 +242,8 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
         return properties;
     }
 
-    private Map<String, JdoNamedQuery> catalogNamedQueries(Set<String> persistableClassNames) {
+    static Map<String, JdoNamedQuery> catalogNamedQueries(
+            Set<String> persistableClassNames, final SpecificationLoader specificationLoader) {
         final Map<String, JdoNamedQuery> namedQueryByName = Maps.newHashMap();
         for (final String persistableClassName: persistableClassNames) {
             final ObjectSpecification spec = specificationLoader.loadSpecification(persistableClassName);
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java
index 2678d50..457632d 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java
@@ -24,20 +24,20 @@ import java.util.Set;
 
 import javax.jdo.PersistenceManagerFactory;
 
+import org.datanucleus.PropertyNames;
+import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
 import org.apache.isis.objectstore.jdo.service.RegisterEntities;
-import org.datanucleus.PropertyNames;
-import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  *
@@ -53,11 +53,11 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
 
     private static final Logger LOG = LoggerFactory.getLogger(PersistenceSessionFactory5.class);
 
-    private final ConfigurationServiceInternal configuration;
-
-    public PersistenceSessionFactory5(final ConfigurationServiceInternal isisConfiguration) {
-        this.configuration = isisConfiguration;
-    }
+//    private final ConfigurationServiceInternal configuration;
+//
+//    public PersistenceSessionFactory5(final ConfigurationServiceInternal isisConfiguration) {
+//        this.configuration = isisConfiguration;
+//    }
 
     public static final String JDO_OBJECTSTORE_CONFIG_PREFIX = "isis.persistor.datanucleus";  // specific to the JDO objectstore
     public static final String DATANUCLEUS_CONFIG_PREFIX = "isis.persistor.datanucleus.impl"; // reserved for datanucleus' own config props
@@ -67,8 +67,8 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
 
     @Programmatic
     @Override
-    public void init(final SpecificationLoader specificationLoader) {
-        this.applicationComponents = createDataNucleusApplicationComponents(configuration, specificationLoader);
+    public void init(final IsisConfigurationDefault configuration) {
+        this.applicationComponents = createDataNucleusApplicationComponents(configuration);
     }
 
     @Programmatic
@@ -78,9 +78,12 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
     }
 
     private DataNucleusApplicationComponents5 createDataNucleusApplicationComponents(
-            final IsisConfiguration configuration, final SpecificationLoader specificationLoader) {
+            final IsisConfiguration configuration) {
 
-        if (applicationComponents == null || applicationComponents.isStale()) {
+        final RegisterEntities registerEntities = new RegisterEntities();
+        final Set<String> classesToBePersisted = registerEntities.getEntityTypes();
+        
+        if (shouldCreate(this.applicationComponents)) {
 
             final IsisConfiguration jdoObjectstoreConfig = configuration.createSubset(
                     JDO_OBJECTSTORE_CONFIG_PREFIX);
@@ -89,15 +92,19 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
             final Map<String, String> datanucleusProps = dataNucleusConfig.asMap();
             addDataNucleusPropertiesIfRequired(datanucleusProps);
 
-            final RegisterEntities registerEntities = new RegisterEntities(specificationLoader);
-            final Set<String> classesToBePersisted = registerEntities.getEntityTypes();
-
-            applicationComponents = new DataNucleusApplicationComponents5(jdoObjectstoreConfig, specificationLoader,
-                    datanucleusProps, classesToBePersisted);
+            DataNucleusApplicationComponents5 applicationComponents1 = 
+                    new DataNucleusApplicationComponents5(jdoObjectstoreConfig,
+                            datanucleusProps, classesToBePersisted);
+            
+            this.applicationComponents = applicationComponents1;
         }
 
         return applicationComponents;
     }
+    
+    private boolean shouldCreate(final DataNucleusApplicationComponents5 applicationComponents) {
+        return applicationComponents == null || applicationComponents.isStale();
+    }
 
     private static void addDataNucleusPropertiesIfRequired(
             final Map<String, String> props) {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/metamodel/IsisJdoRuntimePlugin.java b/core/runtime/src/main/java/org/apache/isis/core/metamodel/IsisJdoRuntimePlugin.java
index 1d33cc7..d60491f 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/metamodel/IsisJdoRuntimePlugin.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/metamodel/IsisJdoRuntimePlugin.java
@@ -17,14 +17,13 @@
 package org.apache.isis.core.metamodel;
 
 import org.apache.isis.commons.internal.context._Plugin;
-import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
 
 public interface IsisJdoRuntimePlugin {
 
     // -- INTERFACE
 
-    public PersistenceSessionFactory getPersistenceSessionFactory(ConfigurationServiceInternal configuration);
+    public PersistenceSessionFactory getPersistenceSessionFactory(/*ConfigurationServiceInternal configuration*/);
 
     // -- LOOKUP
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
index d72c10c..4ec2de2 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
@@ -17,10 +17,9 @@
 package org.apache.isis.core.runtime.system.persistence;
 
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.metamodel.IsisJdoRuntimePlugin;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
-import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 public interface PersistenceSessionFactory {
 
@@ -29,7 +28,7 @@ public interface PersistenceSessionFactory {
     PersistenceSession createPersistenceSession(ServicesInjector servicesInjector,
             AuthenticationSession authenticationSession);
 
-    void init(SpecificationLoader specificationLoader);
+    void init(IsisConfigurationDefault configuration);
 
     boolean isInitialized();
 
@@ -37,8 +36,8 @@ public interface PersistenceSessionFactory {
 
     // -- FACTORY
 
-    static PersistenceSessionFactory of(ConfigurationServiceInternal configuration) {
-        return IsisJdoRuntimePlugin.get().getPersistenceSessionFactory(configuration);
+    static PersistenceSessionFactory of(/*ConfigurationServiceInternal configuration*/) {
+        return IsisJdoRuntimePlugin.get().getPersistenceSessionFactory(/*configuration*/);
     }
 
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
index fb0ba74..6b95018 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
@@ -22,6 +22,9 @@ package org.apache.isis.core.runtime.system.session;
 import java.io.File;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,6 +34,7 @@ import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.fixtures.FixtureClock;
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
 import org.apache.isis.applib.services.fixturespec.FixtureScriptsDefault;
+import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.commons.lang.ListExtensions;
@@ -52,6 +56,7 @@ import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactoryMetamodelRefiner;
 import org.apache.isis.core.runtime.systemusinginstallers.IsisComponentProvider;
 import org.apache.isis.core.runtime.systemusinginstallers.IsisComponentProviderDefault2;
+import org.apache.isis.core.runtime.threadpool.ThreadPoolSupport;
 
 public class IsisSessionFactoryBuilder {
 
@@ -155,7 +160,7 @@ public class IsisSessionFactoryBuilder {
             servicesInjector.addFallbackIfRequired(SpecificationLoader.class, specificationLoader);
 
             // persistenceSessionFactory
-            final PersistenceSessionFactory persistenceSessionFactory = PersistenceSessionFactory.of(configuration);
+            final PersistenceSessionFactory persistenceSessionFactory = PersistenceSessionFactory.of(/*configuration*/);
             servicesInjector.addFallbackIfRequired(PersistenceSessionFactory.class, persistenceSessionFactory);
 
 
@@ -178,33 +183,43 @@ public class IsisSessionFactoryBuilder {
             // yet inject.
             _Context.putSingleton(IsisSessionFactory.class, isisSessionFactory);
 
-            // time to initialize...
-            specificationLoader.init();
-
-            // we need to do this before checking if the metamodel is valid.
-            //
-            // eg ActionChoicesForCollectionParameterFacetFactory metamodel validator requires a runtime...
-            // at o.a.i.core.metamodel.specloader.specimpl.ObjectActionContributee.getServiceAdapter(ObjectActionContributee.java:287)
-            // at o.a.i.core.metamodel.specloader.specimpl.ObjectActionContributee.determineParameters(ObjectActionContributee.java:138)
-            // at o.a.i.core.metamodel.specloader.specimpl.ObjectActionDefault.getParameters(ObjectActionDefault.java:182)
-            // at o.a.i.core.metamodel.facets.actions.action.ActionChoicesForCollectionParameterFacetFactory$1.validate(ActionChoicesForCollectionParameterFacetFactory.java:85)
-            // at o.a.i.core.metamodel.facets.actions.action.ActionChoicesForCollectionParameterFacetFactory$1.visit(ActionChoicesForCollectionParameterFacetFactory.java:76)
-            // at o.a.i.core.metamodel.specloader.validator.MetaModelValidatorVisiting.validate(MetaModelValidatorVisiting.java:47)
-            //
-            // also, required so that can still call isisSessionFactory#doInSession
-            //
-            // eg todoapp has a custom UserSettingsThemeProvider that is called when rendering any page
-            // (including the metamodel invalid page)
-            // at o.a.i.core.runtime.system.session.IsisSessionFactory.doInSession(IsisSessionFactory.java:327)
-            // at todoapp.webapp.UserSettingsThemeProvider.getActiveTheme(UserSettingsThemeProvider.java:36)
-
-            authenticationManager.init(deploymentCategory);
-            authorizationManager.init(deploymentCategory);
-
-            persistenceSessionFactory.init(specificationLoader);
+            final List<Callable<Object>> tasks = _Lists.<Callable<Object>>of(
+                    ()->{
+                        // time to initialize...
+                        specificationLoader.init();
+                        // we need to do this before checking if the metamodel is valid.
+                        //
+                        // eg ActionChoicesForCollectionParameterFacetFactory metamodel validator requires a runtime...
+                        // at o.a.i.core.metamodel.specloader.specimpl.ObjectActionContributee.getServiceAdapter(ObjectActionContributee.java:287)
+                        // at o.a.i.core.metamodel.specloader.specimpl.ObjectActionContributee.determineParameters(ObjectActionContributee.java:138)
+                        // at o.a.i.core.metamodel.specloader.specimpl.ObjectActionDefault.getParameters(ObjectActionDefault.java:182)
+                        // at o.a.i.core.metamodel.facets.actions.action.ActionChoicesForCollectionParameterFacetFactory$1.validate(ActionChoicesForCollectionParameterFacetFactory.java:85)
+                        // at o.a.i.core.metamodel.facets.actions.action.ActionChoicesForCollectionParameterFacetFactory$1.visit(ActionChoicesForCollectionParameterFacetFactory.java:76)
+                        // at o.a.i.core.metamodel.specloader.validator.MetaModelValidatorVisiting.validate(MetaModelValidatorVisiting.java:47)
+                        //
+                        // also, required so that can still call isisSessionFactory#doInSession
+                        //
+                        // eg todoapp has a custom UserSettingsThemeProvider that is called when rendering any page
+                        // (including the metamodel invalid page)
+                        // at o.a.i.core.runtime.system.session.IsisSessionFactory.doInSession(IsisSessionFactory.java:327)
+                        // at todoapp.webapp.UserSettingsThemeProvider.getActiveTheme(UserSettingsThemeProvider.java:36)
+                        authenticationManager.init(deploymentCategory);
+                        authorizationManager.init(deploymentCategory);
+                        return null;
+                    },
+                    ()->{
+                        persistenceSessionFactory.init(configuration);
+                        return null;
+                    }
+                ); 
 
-            isisSessionFactory.constructServices();
+            // execute tasks using a threadpool
+            final List<Future<Object>> futures = ThreadPoolSupport.getInstance().invokeAll(tasks);
+            
+            // wait on this thread for tasks to complete
+            ThreadPoolSupport.join(futures); 
 
+            isisSessionFactory.constructServices();
 
             isisSessionFactory.doInSession(
                     () -> {
@@ -236,13 +251,9 @@ public class IsisSessionFactoryBuilder {
         return ListExtensions.filtered(Arrays.asList(possibleRefiners), MetaModelRefiner.class);
     }
 
-
-
     // region > metaModel validity
     public boolean isMetaModelValid() {
         return IsisContext.getMetaModelInvalidExceptionIfAny() == null;
     }
 
-
-
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
index 3587b75..97c191f 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/service/RegisterEntities.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.objectstore.jdo.service;
 
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -25,14 +26,13 @@ import javax.jdo.annotations.PersistenceCapable;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.AppManifest;
+import org.apache.isis.commons.internal.base._LazyThreadSafe;
 import org.apache.isis.core.metamodel.JdoMetamodelUtil;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 public class RegisterEntities {
 
@@ -45,20 +45,17 @@ public class RegisterEntities {
     @Deprecated
     public final static String PACKAGE_PREFIX_KEY = "isis.persistor.datanucleus.RegisterEntities.packagePrefix";
 
-    // //////////////////////////////////////
-
-
-    // -- entityTypes
-    private final Set<String> entityTypes = Sets.newLinkedHashSet();
-    private final SpecificationLoader specificationLoader;
+    private final _LazyThreadSafe<Set<String>> entityTypes = _LazyThreadSafe.of(this::findEntityTypes);
 
     public Set<String> getEntityTypes() {
-        return entityTypes;
+        return entityTypes.get();
     }
 
+    // -- HELPER
 
-    public RegisterEntities(final SpecificationLoader specificationLoader) {
-        this.specificationLoader = specificationLoader;
+    private Set<String> findEntityTypes() {
+        
+        Set<String> entityTypes = new LinkedHashSet<String>();
 
         Set<Class<?>> persistenceCapableTypes = AppManifest.Registry.instance().getPersistenceCapableTypes();
 
@@ -74,13 +71,15 @@ public class RegisterEntities {
             if(!JdoMetamodelUtil.isPersistenceEnhanced(persistenceCapableType)) {
                 classNamesNotEnhanced.add(persistenceCapableType.getCanonicalName());
             }
-            this.entityTypes.add(persistenceCapableType.getCanonicalName());
+            entityTypes.add(persistenceCapableType.getCanonicalName());
         }
 
         if(!classNamesNotEnhanced.isEmpty()) {
             final String classNamesNotEnhancedStr = Joiner.on("\n* ").join(classNamesNotEnhanced);
             throw new IllegalStateException("Non-enhanced @PersistenceCapable classes found, will abort.  The classes in error are:\n\n* " + classNamesNotEnhancedStr + "\n\nDid the DataNucleus enhancer run correctly?\n");
         }
+        
+        return entityTypes;
     }
 
 
@@ -98,8 +97,4 @@ public class RegisterEntities {
     }
 
 
-    SpecificationLoader getSpecificationLoader() {
-        return specificationLoader;
-    }
-
 }


[isis] 01/03: ISIS-1974: (porting from 1.16.x) support sequential execution

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 539e004310ef7c2511e699ea01e00dca538304a8
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Aug 31 07:00:09 2018 +0200

    ISIS-1974: (porting from 1.16.x)  support sequential execution
    
    in ThreadPoolSupport
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1895
---
 .../core/runtime/threadpool/ThreadPoolSupport.java | 69 ++++++++++++++++++----
 1 file changed, 56 insertions(+), 13 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/runtime/threadpool/ThreadPoolSupport.java b/core/metamodel/src/main/java/org/apache/isis/core/runtime/threadpool/ThreadPoolSupport.java
index 5fb798e..7a37e70 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/runtime/threadpool/ThreadPoolSupport.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/runtime/threadpool/ThreadPoolSupport.java
@@ -19,6 +19,9 @@
 
 package org.apache.isis.core.runtime.threadpool;
 
+import static org.apache.isis.commons.internal.base._NullSafe.isEmpty;
+
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
@@ -28,12 +31,16 @@ import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
+import javax.annotation.Nullable;
 
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.context._Context;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.context._Context;
+
 /**
  * ThreadPoolSupport is application-scoped, meaning ThreadPoolSupport is closed on
  * application's end of life-cycle.
@@ -48,6 +55,7 @@ public final class ThreadPoolSupport implements AutoCloseable {
 
     private final ThreadGroup group;
     private final ThreadPoolExecutor executor;
+    private final ThreadPoolExecutor sequentialExecutor;
 
     private ThreadPoolSupport() {
 
@@ -56,21 +64,26 @@ public final class ThreadPoolSupport implements AutoCloseable {
         final int corePoolSize = Runtime.getRuntime().availableProcessors();
         final int maximumPoolSize = Runtime.getRuntime().availableProcessors();
         final int keepAliveTimeSecs = 5;
+        
+        final ThreadFactory threadFactory = (Runnable r) -> new Thread(group, r);
 
         final int queueCapacity = 25;
-        final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(queueCapacity);
-
+        final Supplier<BlockingQueue<Runnable>> workQueueFactory = 
+                ()->new LinkedBlockingQueue<>(queueCapacity);
+        
+        
         executor = new ThreadPoolExecutor(
                 corePoolSize,
                 maximumPoolSize,
                 keepAliveTimeSecs, TimeUnit.SECONDS,
-                workQueue,
-                new ThreadFactory() {
-                    @Override
-                    public Thread newThread(final Runnable r) {
-                        return new Thread(group, r);
-                    }
-                });
+                workQueueFactory.get(),
+                threadFactory);
+        
+        sequentialExecutor = new ThreadPoolExecutor(1, 1, // fixed size = 1
+                keepAliveTimeSecs, TimeUnit.MILLISECONDS,
+                workQueueFactory.get(),
+                threadFactory);
+        
     }
 
     public static List<Object> join(final List<Future<Object>> futures) {
@@ -100,7 +113,16 @@ public final class ThreadPoolSupport implements AutoCloseable {
         return null;
     }
 
-    public List<Future<Object>> invokeAll(final List<Callable<Object>> callables) {
+    /**
+     * Executes specified {@code callables} on the default executor.  
+     * See {@link ThreadPoolExecutor#invokeAll(java.util.Collection)}
+     * @param callables nullable
+     * @return non-null
+     */
+    public List<Future<Object>> invokeAll(@Nullable final List<Callable<Object>> callables) {
+        if(isEmpty(callables)) {
+            return Collections.emptyList();
+        }
         try {
             return executor.invokeAll(callables);
         } catch (InterruptedException e) {
@@ -108,13 +130,34 @@ public final class ThreadPoolSupport implements AutoCloseable {
         }
     }
 
+    /**
+     * Executes specified {@code callables} on the sequential executor in sequence, one by one.
+     * @param callables nullable
+     * @return non-null
+     */
+    public List<Future<Object>> invokeAllSequential(@Nullable final List<Callable<Object>> callables) {
+        if(isEmpty(callables)) {
+            return Collections.emptyList();
+        }
+        try {
+            return sequentialExecutor.invokeAll(callables);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
     public static ThreadPoolSupport getInstance() {
         return _Context.computeIfAbsent(ThreadPoolSupport.class, __-> new ThreadPoolSupport());
     }
 
     @Override
     public void close() throws Exception {
-        executor.shutdown();
+        try {
+            executor.shutdown();
+        } finally {
+            // in case the previous throws, continue execution here
+            sequentialExecutor.shutdown();            
+        }
     }
 
 }