Author: mpetria
Date: Mon Feb  1 15:36:33 2016
New Revision: 1727953

URL: http://svn.apache.org/viewvc?rev=1727953&view=rev
Log:
SLING-5473: reduce locking for shared distribution packages

Modified:
    
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java
    
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java
    
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackage.java
    
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackageBuilder.java
    
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackageBuilder.java
    
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageImporterServlet.java

Modified: 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java?rev=1727953&r1=1727952&r2=1727953&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java
 (original)
+++ 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/agent/impl/SimpleDistributionAgent.java
 Mon Feb  1 15:36:33 2016
@@ -435,6 +435,8 @@ public class SimpleDistributionAgent imp
             distributionPackage = 
distributionPackageExporter.getPackage(agentResourceResolver, 
queueItem.getId());
 
             if (distributionPackage != null) {
+                final long getTime = System.currentTimeMillis();
+
                 final DistributionRequestType requestType = 
distributionPackage.getInfo().getRequestType();
                 final long packageSize = distributionPackage.getSize();
                 final String[] paths = 
distributionPackage.getInfo().getPaths();
@@ -447,10 +449,10 @@ public class SimpleDistributionAgent imp
                     removeItemFromQueue = true;
                     final long endTime = System.currentTimeMillis();
 
-                    log.info("[{}] PACKAGE-DELIVERED {}: {} paths={}, 
time={}ms, importTime={}ms, size={}B", new Object[] {
+                    log.info("[{}] PACKAGE-DELIVERED {}: {} paths={}, 
importTime={}ms, execTime={}ms, size={}B", new Object[] {
                             queueName, requestId,
                             requestType, paths,
-                            endTime - globalStartTime, endTime - startTime,
+                            endTime - startTime, endTime - globalStartTime,
                             packageSize
                     });
                 } catch (RecoverableDistributionException e) {
@@ -525,7 +527,9 @@ public class SimpleDistributionAgent imp
 
         if (resourceResolver != null) {
             try {
-                resourceResolver.commit();
+                if (resourceResolver.hasChanges()) {
+                    resourceResolver.commit();
+                }
             } catch (PersistenceException e) {
                 log.error("cannot commit changes to resource resolver", e);
             } finally {
@@ -603,11 +607,16 @@ public class SimpleDistributionAgent imp
             DistributionQueueItem queueItem = queueEntry.getItem();
 
             try {
+                final long startTime = System.currentTimeMillis();
+
                 log.debug("[{}] ITEM-PROCESS processing item={}", queueName, 
queueItem);
 
                 boolean success = processQueueItem(queueName, queueEntry);
 
-                log.debug("[{}] ITEM-PROCESSED item={}, status={}", queueName, 
queueItem, success);
+                final long endTime = System.currentTimeMillis();
+
+
+                log.debug("[{}] ITEM-PROCESSED item={}, status={}, 
processingTime={}", queueName, queueItem, success, endTime - startTime);
 
                 return success;
 

Modified: 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java?rev=1727953&r1=1727952&r2=1727953&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java
 (original)
+++ 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/AbstractDistributionPackageBuilder.java
 Mon Feb  1 15:36:33 2016
@@ -162,7 +162,9 @@ public abstract class AbstractDistributi
     protected void ungetSession(Session session) {
         if (session != null) {
             try {
-                session.save();
+                if (session.hasPendingChanges()) {
+                    session.save();
+                }
             } catch (RepositoryException e) {
                 log.debug("Cannot save session", e);
             }

Modified: 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackage.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackage.java?rev=1727953&r1=1727952&r2=1727953&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackage.java
 (original)
+++ 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackage.java
 Mon Feb  1 15:36:33 2016
@@ -22,6 +22,8 @@ import javax.annotation.Nonnull;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
@@ -35,19 +37,17 @@ public class DefaultSharedDistributionPa
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     static final String REFERENCE_ROOT_NODE = "refs";
-    private final Object lock;
 
     private final ResourceResolver resourceResolver;
     private final String packagePath;
     private final DistributionPackage distributionPackage;
     private final String packageName;
 
-    public DefaultSharedDistributionPackage(Object lock, ResourceResolver 
resourceResolver, String packageName, String packagePath, DistributionPackage 
distributionPackage) {
+    public DefaultSharedDistributionPackage(ResourceResolver resourceResolver, 
String packageName, String packagePath, DistributionPackage 
distributionPackage) {
         this.resourceResolver = resourceResolver;
         this.packageName = packageName;
         this.packagePath = packagePath;
         this.distributionPackage = distributionPackage;
-        this.lock = lock;
     }
 
     public void acquire(@Nonnull String holderName) {
@@ -72,14 +72,17 @@ public class DefaultSharedDistributionPa
         }
 
         try {
-            deleteHolderResource(holderName);
+            boolean doPackageDelete = deleteHolderResource(holderName);
 
-            boolean doPackageDelete = deleteIfEmpty();
 
             if (doPackageDelete) {
                 distributionPackage.delete();
             }
 
+            if (resourceResolver.hasChanges()) {
+                resourceResolver.commit();
+            }
+
             log.debug("released package {} from holder {} delete {}", new 
Object[]{packagePath, holderName, doPackageDelete});
         } catch (PersistenceException e) {
             log.error("cannot release package", e);
@@ -114,7 +117,7 @@ public class DefaultSharedDistributionPa
     public void delete() {
 
         try {
-            deleteHolderRoot();
+            deleteProxy();
         } catch (PersistenceException e) {
             log.error("cannot delete shared resource", e);
         }
@@ -135,7 +138,6 @@ public class DefaultSharedDistributionPa
     private Resource getProxyResource() {
         String holderPath = packagePath;
 
-        resourceResolver.refresh();
         return resourceResolver.getResource(holderPath);
     }
 
@@ -153,64 +155,48 @@ public class DefaultSharedDistributionPa
 
     private void createHolderResource(String holderName) throws 
PersistenceException {
 
-        synchronized (lock) {
-            Resource holderRoot = getHolderRootResource();
-
-            if (holderRoot == null) {
-                return;
-            }
-
-            Resource holder = holderRoot.getChild(holderName);
+        Resource holderRoot = getHolderRootResource();
 
-            if (holder != null) {
-                return;
-            }
+        if (holderRoot == null) {
+            return;
+        }
 
-            resourceResolver.create(holderRoot, holderName, 
Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object) 
"sling:Folder"));
-            resourceResolver.commit();
+        Resource holder = holderRoot.getChild(holderName);
 
+        if (holder != null) {
+            return;
         }
-    }
-
-    private void deleteHolderResource(String holderName) throws 
PersistenceException {
 
-        synchronized (lock) {
-            Resource holderRoot = getHolderRootResource();
+        resourceResolver.create(holderRoot, holderName, 
Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object) 
"sling:Folder"));
+        resourceResolver.commit();
+    }
 
-            if (holderRoot == null) {
-                return;
-            }
+    private boolean deleteHolderResource(String holderName) throws 
PersistenceException {
+        boolean doPackageDelete = false;
+        Resource holderRoot = getHolderRootResource();
 
+        if (holderRoot != null) {
             Resource holder = holderRoot.getChild(holderName);
 
-            if (holder == null) {
-                return;
+            if (holder != null) {
+                resourceResolver.delete(holder);
             }
-
-            resourceResolver.delete(holder);
-            resourceResolver.commit();
         }
-    }
 
-    private void deleteHolderRoot() throws PersistenceException {
-        synchronized (lock) {
+        if (!holderRoot.hasChildren()) {
             Resource resource = getProxyResource();
             resourceResolver.delete(resource);
-            resourceResolver.commit();
+            doPackageDelete = true;
         }
 
+        return doPackageDelete;
     }
 
-    private boolean deleteIfEmpty() throws PersistenceException {
-        synchronized (lock) {
-            Resource holderRoot = getHolderRootResource();
-            if (holderRoot != null && !holderRoot.hasChildren()) {
-                deleteHolderRoot();
-                return true;
-            }
-        }
-
-        return false;
+    private void deleteProxy() throws PersistenceException {
+        Resource resource = getProxyResource();
+        resourceResolver.delete(resource);
+        resourceResolver.commit();
     }
 
+
 }

Modified: 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackageBuilder.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackageBuilder.java?rev=1727953&r1=1727952&r2=1727953&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackageBuilder.java
 (original)
+++ 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/DefaultSharedDistributionPackageBuilder.java
 Mon Feb  1 15:36:33 2016
@@ -86,7 +86,7 @@ public class DefaultSharedDistributionPa
         }
 
         String packagePath = getPathFromName(packageName);
-        DistributionPackage sharedDistributionPackage = new 
DefaultSharedDistributionPackage(repolock, resourceResolver, packageName, 
packagePath, distributionPackage);
+        DistributionPackage sharedDistributionPackage = new 
DefaultSharedDistributionPackage(resourceResolver, packageName, packagePath, 
distributionPackage);
 
         log.debug("created shared package {} for {}", 
sharedDistributionPackage.getId(), distributionPackage.getId());
         return sharedDistributionPackage;
@@ -110,7 +110,7 @@ public class DefaultSharedDistributionPa
 
         String packagePath = getPathFromName(packageName);
 
-        DistributionPackage sharedDistributionPackage = new 
DefaultSharedDistributionPackage(repolock, resourceResolver, packageName, 
packagePath, distributionPackage);
+        DistributionPackage sharedDistributionPackage = new 
DefaultSharedDistributionPackage(resourceResolver, packageName, packagePath, 
distributionPackage);
 
         log.debug("created shared package {} for {}", 
sharedDistributionPackage.getId(), distributionPackage.getId());
         return sharedDistributionPackage;
@@ -137,7 +137,7 @@ public class DefaultSharedDistributionPa
 
         String packagePath = getPathFromName(packageName);
 
-        return new DefaultSharedDistributionPackage(repolock, 
resourceResolver, packageName, packagePath, distributionPackage);
+        return new DefaultSharedDistributionPackage(resourceResolver, 
packageName, packagePath, distributionPackage);
     }
 
     public boolean installPackage(@Nonnull ResourceResolver resourceResolver, 
@Nonnull DistributionPackage distributionPackage) throws DistributionException {
@@ -169,6 +169,9 @@ public class DefaultSharedDistributionPa
 
         String packagePath = getPathFromName(name);
 
+        Resource packagesRoot = getPackagesRoot(resourceResolver);
+
+        // TODO: Hack! this block is not strictly necessary to be synchronized 
but performance tests run faster if it is
         synchronized (repolock) {
             Resource resource = 
ResourceUtil.getOrCreateResource(resourceResolver, packagePath,
                     "sling:Folder", "sling:Folder", false);
@@ -182,6 +185,7 @@ public class DefaultSharedDistributionPa
             resourceResolver.commit();
         }
 
+
         return name;
     }
 
@@ -206,4 +210,20 @@ public class DefaultSharedDistributionPa
 
         return properties.get(PN_ORIGINAL_ID, null);
     }
+
+
+    Resource getPackagesRoot(ResourceResolver resourceResolver) throws 
PersistenceException {
+        Resource packagesRoot = 
resourceResolver.getResource(sharedPackagesRoot);
+
+        if (packagesRoot != null) {
+            return packagesRoot;
+        }
+
+        synchronized (repolock) {
+            resourceResolver.refresh();
+            packagesRoot = ResourceUtil.getOrCreateResource(resourceResolver, 
sharedPackagesRoot, "sling:Folder", "sling:Folder", true);
+        }
+
+        return packagesRoot;
+    }
 }

Modified: 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackageBuilder.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackageBuilder.java?rev=1727953&r1=1727952&r2=1727953&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackageBuilder.java
 (original)
+++ 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/serialization/impl/vlt/JcrVaultDistributionPackageBuilder.java
 Mon Feb  1 15:36:33 2016
@@ -78,6 +78,8 @@ public class JcrVaultDistributionPackage
     private final TreeMap<String, List<String>> filters;
     private final boolean useBinaryReferences;
 
+    private final Object repolock = new Object();
+
     public JcrVaultDistributionPackageBuilder(String type, Packaging 
packaging, ImportMode importMode, AccessControlHandling aclHandling, String[] 
packageRoots, String[] filterRules, String tempFilesFolder, boolean 
useBinaryReferences) {
         super(type);
 
@@ -231,11 +233,25 @@ public class JcrVaultDistributionPackage
     }
 
     private Node getPackageRoot(Session session) throws RepositoryException {
-        Node tempRoot = 
JcrUtils.getNodeIfExists(AbstractDistributionPackage.PACKAGES_ROOT, session);
-        if (tempPackagesNode != null && tempRoot != null) {
-            return JcrUtils.getOrCreateByPath(tempRoot, tempPackagesNode, 
false, "sling:Folder", "sling:Folder", true);
+        Node packageRoot = 
JcrUtils.getNodeIfExists(AbstractDistributionPackage.PACKAGES_ROOT + "/" + 
tempPackagesNode, session);
+
+        if (packageRoot != null) {
+            return packageRoot;
+        }
+
+        synchronized (repolock) {
+            session.refresh(false);
+
+            Node tempRoot = 
JcrUtils.getNodeIfExists(AbstractDistributionPackage.PACKAGES_ROOT, session);
+
+            if (tempRoot == null) {
+                tempRoot = 
JcrUtils.getOrCreateByPath(AbstractDistributionPackage.PACKAGES_ROOT, 
"sling:Folder", "sling:Folder", session, true);
+            }
+
+            packageRoot = JcrUtils.getOrCreateByPath(tempRoot, 
tempPackagesNode, false, "sling:Folder", "sling:Folder", true);
+
         }
 
-        throw new RepositoryException("Cannot read "+ 
AbstractDistributionPackage.PACKAGES_ROOT);
+        return packageRoot;
     }
 }

Modified: 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageImporterServlet.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageImporterServlet.java?rev=1727953&r1=1727952&r2=1727953&view=diff
==============================================================================
--- 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageImporterServlet.java
 (original)
+++ 
sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/servlet/DistributionPackageImporterServlet.java
 Mon Feb  1 15:36:33 2016
@@ -62,7 +62,9 @@ public class DistributionPackageImporter
             
             DistributionPackageInfo distributionPackageInfo = 
distributionPackageImporter.importStream(resourceResolver, stream);
 
-            log.info("Package {} imported successfully", 
distributionPackageInfo);
+            long end = System.currentTimeMillis();
+
+            log.info("Package {} imported successfully in {}ms", 
distributionPackageInfo, end - start);
             ServletJsonUtils.writeJson(response, 200, "package imported 
successfully");
 
         } catch (final Throwable e) {


Reply via email to