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/09/04 18:05:21 UTC

[isis] 02/02: ISIS-1974: fixes concurrent PersistenceSessionFactory initialization for 2.0.0-M2-SNAPSHOT

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 967dccee967fb329fb76f3443305f9c9477d3847
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Sep 4 20:04:19 2018 +0200

    ISIS-1974: fixes concurrent PersistenceSessionFactory initialization for
    2.0.0-M2-SNAPSHOT
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1974
---
 .../persistence/PersistenceSessionFactory5.java    | 73 ++++++++++++----------
 1 file changed, 39 insertions(+), 34 deletions(-)

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 457632d..93a450c 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
@@ -20,6 +20,7 @@
 package org.apache.isis.core.runtime.system.persistence;
 
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 
 import javax.jdo.PersistenceManagerFactory;
@@ -30,6 +31,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.commons.internal.base._LazyThreadSafe;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
@@ -53,57 +55,41 @@ 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;
-//    }
-
     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
 
 
-    private DataNucleusApplicationComponents5 applicationComponents;
+    private final _LazyThreadSafe<DataNucleusApplicationComponents5> applicationComponents = 
+            _LazyThreadSafe.of(this::createDataNucleusApplicationComponents);
 
+    private IsisConfiguration configuration;
+    
     @Programmatic
     @Override
     public void init(final IsisConfigurationDefault configuration) {
-        this.applicationComponents = createDataNucleusApplicationComponents(configuration);
+        this.configuration = configuration;
     }
 
     @Programmatic
     @Override
     public boolean isInitialized() {
-        return this.applicationComponents != null;
+        return this.configuration != null;
     }
 
-    private DataNucleusApplicationComponents5 createDataNucleusApplicationComponents(
-            final IsisConfiguration configuration) {
+    private DataNucleusApplicationComponents5 createDataNucleusApplicationComponents() {
 
         final RegisterEntities registerEntities = new RegisterEntities();
         final Set<String> classesToBePersisted = registerEntities.getEntityTypes();
         
-        if (shouldCreate(this.applicationComponents)) {
+        final IsisConfiguration jdoObjectstoreConfig = configuration.createSubset(
+                JDO_OBJECTSTORE_CONFIG_PREFIX);
 
-            final IsisConfiguration jdoObjectstoreConfig = configuration.createSubset(
-                    JDO_OBJECTSTORE_CONFIG_PREFIX);
+        final IsisConfiguration dataNucleusConfig = configuration.createSubset(DATANUCLEUS_CONFIG_PREFIX);
+        final Map<String, String> datanucleusProps = dataNucleusConfig.asMap();
+        addDataNucleusPropertiesIfRequired(datanucleusProps);
 
-            final IsisConfiguration dataNucleusConfig = configuration.createSubset(DATANUCLEUS_CONFIG_PREFIX);
-            final Map<String, String> datanucleusProps = dataNucleusConfig.asMap();
-            addDataNucleusPropertiesIfRequired(datanucleusProps);
-
-            DataNucleusApplicationComponents5 applicationComponents1 = 
-                    new DataNucleusApplicationComponents5(jdoObjectstoreConfig,
-                            datanucleusProps, classesToBePersisted);
-            
-            this.applicationComponents = applicationComponents1;
-        }
-
-        return applicationComponents;
-    }
-    
-    private boolean shouldCreate(final DataNucleusApplicationComponents5 applicationComponents) {
-        return applicationComponents == null || applicationComponents.isStale();
+        return new DataNucleusApplicationComponents5(jdoObjectstoreConfig,
+                        datanucleusProps, classesToBePersisted);
     }
 
     private static void addDataNucleusPropertiesIfRequired(
@@ -169,10 +155,11 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
         if(!isInitialized()) {
             return;
         }
-        if(applicationComponents != null) {
-            applicationComponents.shutdown();
-            applicationComponents = null;
+        if(applicationComponents.isMemoized()) {
+            applicationComponents.get().shutdown();
+            applicationComponents.clear();
         }
+        this.configuration = null;
     }
 
     /**
@@ -184,9 +171,15 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
             final ServicesInjector servicesInjector,
             final AuthenticationSession authenticationSession) {
 
+        Objects.requireNonNull(applicationComponents, "PersistenceSession5 requires initialization. "+this.hashCode());
+        
         final FixturesInstalledFlag fixturesInstalledFlag = this;
+        
+        //[ahuber] if stale force recreate
+        guardAgainstStaleState();
+        
         final PersistenceManagerFactory persistenceManagerFactory =
-                applicationComponents.getPersistenceManagerFactory();
+                applicationComponents.get().getPersistenceManagerFactory();
 
         return new PersistenceSession5(
                 servicesInjector,
@@ -207,6 +200,18 @@ implements PersistenceSessionFactory, ApplicationScopedComponent, FixturesInstal
     public void setFixturesInstalled(final Boolean fixturesInstalled) {
         this.fixturesInstalled = fixturesInstalled;
     }
+    
+    // [ahuber] JRebel support, not tested at all
+    private void guardAgainstStaleState() {
+        if(applicationComponents.get().isStale()) {
+            try {
+                applicationComponents.get().shutdown();
+            } catch (Exception e) {
+                // ignore
+            }
+            applicationComponents.clear();
+        }
+    }
 
 
 }