You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by dg...@apache.org on 2019/08/29 08:50:43 UTC

[ignite] branch master updated: IGNITE-12104 Check deployment from cache before to load it from local or version storage

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8d44c32  IGNITE-12104 Check deployment from cache before to load it from local or version storage
8d44c32 is described below

commit 8d44c327efd9b1a834a0aa01cd1e37c9b1e1cbd3
Author: Vladislav Pyatkov <vl...@gmail.com>
AuthorDate: Thu Aug 29 11:50:31 2019 +0300

    IGNITE-12104 Check deployment from cache before to load it from local or version storage
    
    Signed-off-by: Dmitriy Govorukhin <dm...@gmail.com>
---
 .../managers/deployment/GridDeployment.java        |   4 +-
 .../deployment/GridDeploymentLocalStore.java       |   9 +-
 .../managers/deployment/GridDeploymentManager.java |  12 +-
 .../deployment/GridDeploymentPerLoaderStore.java   |   7 +-
 .../deployment/GridDeploymentPerVersionStore.java  |  50 ++++---
 .../managers/deployment/GridDeploymentStore.java   |   6 +
 ...ntTiesLoadClassDirectlyFromClassLoaderTest.java | 144 +++++++++++++++++++++
 .../ignite/testsuites/IgniteP2PSelfTestSuite.java  |   2 +
 8 files changed, 208 insertions(+), 26 deletions(-)

diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeployment.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeployment.java
index 4721e8d..c47649d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeployment.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeployment.java
@@ -454,7 +454,7 @@ public class GridDeployment extends GridMetadataAwareAdapter implements GridDepl
 
         if (cls == null) {
             try {
-                cls = Class.forName(clsName, true, clsLdr);
+                cls = U.forName(clsName, clsLdr);
 
                 Class<?> cur = clss.putIfAbsent(clsName, cls);
 
@@ -475,7 +475,7 @@ public class GridDeployment extends GridMetadataAwareAdapter implements GridDepl
                         return cls;
                     else if (!a.equals(clsName)) {
                         try {
-                            cls = Class.forName(a, true, clsLdr);
+                            cls = U.forName(a, clsLdr);
                         }
                         catch (ClassNotFoundException ignored0) {
                             continue;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
index 10f0695..c308f85 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentLocalStore.java
@@ -188,7 +188,7 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
                 // Check that class can be loaded.
                 String clsName = meta.className();
 
-                Class<?> cls = Class.forName(clsName != null ? clsName : alias, true, ldr);
+                Class<?> cls = U.forName(clsName != null ? clsName : alias, ldr);
 
                 spi.register(ldr, cls);
 
@@ -227,6 +227,11 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
         return dep;
     }
 
+    /** {@inheritDoc} */
+    @Override public GridDeployment searchDeploymentCache(GridDeploymentMetadata meta) {
+        return deployment(meta.alias());
+    }
+
     /**
      * @param alias Class alias.
      * @return Deployment.
@@ -445,7 +450,7 @@ class GridDeploymentLocalStore extends GridDeploymentStoreAdapter {
 
             evt.message(msg);
             evt.node(ctx.discovery().localNode());
-            evt.type(isTask(cls) ? EVT_CLASS_DEPLOY_FAILED : EVT_TASK_DEPLOY_FAILED);
+            evt.type(isTask ? EVT_CLASS_DEPLOY_FAILED : EVT_TASK_DEPLOY_FAILED);
             evt.alias(taskName);
 
             ctx.event().record(evt);
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
index f99f9fc..b20dd70 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentManager.java
@@ -458,6 +458,11 @@ public class GridDeploymentManager extends GridManagerAdapter<DeploymentSpi> {
                 }
             }
 
+            GridDeployment dep = verStore.searchDeploymentCache(meta);
+
+            if (dep != null)
+                return dep;
+
             if (reuse) {
                 GridDeployment locDep = locStore.getDeployment(meta);
 
@@ -496,7 +501,12 @@ public class GridDeploymentManager extends GridManagerAdapter<DeploymentSpi> {
         // Private or Isolated mode.
         meta.record(false);
 
-        GridDeployment dep = locStore.getDeployment(meta);
+        GridDeployment dep = ldrStore.searchDeploymentCache(meta);
+
+        if (dep != null)
+            return dep;
+
+        dep = locStore.getDeployment(meta);
 
         if (sndNodeId.equals(ctx.localNodeId())) {
             if (dep == null)
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
index 4ba308c..0477523 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerLoaderStore.java
@@ -219,7 +219,7 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter {
         IsolatedDeployment dep;
 
         synchronized (mux) {
-            dep = cache.get(meta.classLoaderId());
+            dep = (IsolatedDeployment)searchDeploymentCache(meta);
 
             if (dep == null) {
                 long undeployTimeout = 0;
@@ -332,6 +332,11 @@ public class GridDeploymentPerLoaderStore extends GridDeploymentStoreAdapter {
     }
 
     /** {@inheritDoc} */
+    @Override public GridDeployment searchDeploymentCache(GridDeploymentMetadata meta) {
+        return cache.get(meta.classLoaderId());
+    }
+
+    /** {@inheritDoc} */
     @Override public void addParticipants(Map<UUID, IgniteUuid> allParticipants,
         Map<UUID, IgniteUuid> addedParticipants) {
         assert false;
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
index dc59092..d537d39 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentPerVersionStore.java
@@ -278,6 +278,26 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter {
     }
 
     /** {@inheritDoc} */
+    @Override public GridDeployment searchDeploymentCache(GridDeploymentMetadata meta) {
+        List<SharedDeployment> deps = null;
+
+        synchronized (mux) {
+            deps = cache.get(meta.userVersion());
+        }
+
+        if (deps != null) {
+            assert !deps.isEmpty();
+
+            for (SharedDeployment d : deps) {
+                if (d.hasParticipant(meta.senderNodeId(), meta.classLoaderId()))
+                    return d;
+            }
+        }
+
+        return null;
+    }
+
+    /** {@inheritDoc} */
     @Override @Nullable public GridDeployment getDeployment(GridDeploymentMetadata meta) {
         assert meta != null;
 
@@ -356,22 +376,14 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter {
                     return null;
                 }
 
-                List<SharedDeployment> deps = cache.get(meta.userVersion());
-
-                if (deps != null) {
-                    assert !deps.isEmpty();
+                dep = (SharedDeployment)searchDeploymentCache(meta);
 
-                    for (SharedDeployment d : deps) {
-                        if (d.hasParticipant(meta.senderNodeId(), meta.classLoaderId()) ||
-                            meta.senderNodeId().equals(ctx.localNodeId())) {
-                            // Done.
-                            dep = d;
+                if (dep == null) {
+                    List<SharedDeployment> deps = cache.get(meta.userVersion());
 
-                            break;
-                        }
-                    }
+                    if (deps != null) {
+                        assert !deps.isEmpty();
 
-                    if (dep == null) {
                         checkRedeploy(meta);
 
                         // Find existing deployments that need to be checked
@@ -413,12 +425,12 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter {
                             deps.add(dep);
                         }
                     }
-                }
-                else {
-                    checkRedeploy(meta);
+                    else {
+                        checkRedeploy(meta);
 
-                    // Create peer class loader.
-                    dep = createNewDeployment(meta, true);
+                        // Create peer class loader.
+                        dep = createNewDeployment(meta, true);
+                    }
                 }
             }
 
@@ -1188,8 +1200,6 @@ public class GridDeploymentPerVersionStore extends GridDeploymentStoreAdapter {
             assert nodeId != null;
             assert ldrId != null;
 
-            assert Thread.holdsLock(mux);
-
             return classLoader().hasRegisteredNode(nodeId, ldrId);
         }
 
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentStore.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentStore.java
index 97605dc..5105f6b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/deployment/GridDeploymentStore.java
@@ -59,6 +59,12 @@ public interface GridDeploymentStore {
     @Nullable public GridDeployment getDeployment(GridDeploymentMetadata meta);
 
     /**
+     * @param meta Deployment meatdata.
+     * @return Grid deployment instance if it was finded in cache, {@code null} otherwise.
+     */
+    @Nullable public GridDeployment searchDeploymentCache(GridDeploymentMetadata meta);
+
+    /**
      * Gets class loader based on ID.
      *
      *
diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest.java
new file mode 100644
index 0000000..6f4e91b
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.p2p;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.configuration.DeploymentMode;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteCallable;
+import org.apache.ignite.testframework.config.GridTestProperties;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.apache.ignite.testframework.junits.common.GridCommonTest;
+import org.junit.Test;
+
+/**
+ * Checks count of tries to load class directly from class loader.
+ */
+@GridCommonTest(group = "P2P")
+public class GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest extends GridCommonAbstractTest {
+    /** P2P class path property. */
+    public static final String CLS_PATH_PROPERTY = "p2p.uri.cls";
+
+    /** Compute task name. */
+    private static String COMPUTE_TASK_NAME = "org.apache.ignite.tests.p2p.compute.ExternalCallable";
+
+    /** Deployment mode. */
+    private DeploymentMode depMode;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        return super.getConfiguration(igniteInstanceName)
+            .setDeploymentMode(depMode)
+            .setPeerClassLoadingEnabled(true);
+    }
+
+    /**
+     * @throws Exception if error occur.
+     */
+    public void executeP2PTask(DeploymentMode depMode) throws Exception {
+        try {
+            CountTriesClassLoader testCountLdr = new CountTriesClassLoader(Thread.currentThread()
+                .getContextClassLoader());
+
+            this.depMode = depMode;
+
+            Thread.currentThread().setContextClassLoader(testCountLdr);
+
+            String path = GridTestProperties.getProperty(CLS_PATH_PROPERTY);
+
+            ClassLoader urlClsLdr = new URLClassLoader(new URL[] {new URL(path)}, testCountLdr);
+
+            Ignite ignite = startGrids(2);
+
+            ignite.compute(ignite.cluster().forRemotes()).call((IgniteCallable)urlClsLdr.loadClass(COMPUTE_TASK_NAME)
+                .newInstance());
+
+            int count = testCountLdr.count;
+
+            ignite.compute(ignite.cluster().forRemotes()).call((IgniteCallable)urlClsLdr.loadClass(COMPUTE_TASK_NAME)
+                .newInstance());
+            ignite.compute(ignite.cluster().forRemotes()).call((IgniteCallable)urlClsLdr.loadClass(COMPUTE_TASK_NAME)
+                .newInstance());
+            ignite.compute(ignite.cluster().forRemotes()).call((IgniteCallable)urlClsLdr.loadClass(COMPUTE_TASK_NAME)
+                .newInstance());
+
+            assertEquals(count, testCountLdr.count);
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     * @throws Exception if error occur.
+     */
+    @Test
+    public void testPrivateMode() throws Exception {
+        executeP2PTask(DeploymentMode.PRIVATE);
+    }
+
+    /**
+     * @throws Exception if error occur.
+     */
+    @Test
+    public void testIsolatedMode() throws Exception {
+        executeP2PTask(DeploymentMode.ISOLATED);
+    }
+
+    /**
+     * @throws Exception if error occur.
+     */
+    @Test
+    public void testContinuousMode() throws Exception {
+        executeP2PTask(DeploymentMode.CONTINUOUS);
+    }
+
+    /**
+     * @throws Exception if error occur.
+     */
+    @Test
+    public void testSharedMode() throws Exception {
+        executeP2PTask(DeploymentMode.SHARED);
+    }
+
+    /**
+     * Test count class loader.
+     */
+    private static class CountTriesClassLoader extends ClassLoader {
+        /** Count of tries. */
+        int count = 0;
+
+        /**
+         * @param parent Parent class loader.
+         */
+        public CountTriesClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+
+        /** {@inheritDoc} */
+        @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            if (COMPUTE_TASK_NAME.equals(name))
+                U.dumpStack(log, "Try to load class: " + name + " " + ++count);
+
+            return super.loadClass(name, resolve);
+        }
+    }
+}
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
index 6651a69..9c6bc3f 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteP2PSelfTestSuite.java
@@ -26,6 +26,7 @@ import org.apache.ignite.p2p.GridP2PDifferentClassLoaderSelfTest;
 import org.apache.ignite.p2p.GridP2PDoubleDeploymentSelfTest;
 import org.apache.ignite.p2p.GridP2PHotRedeploymentSelfTest;
 import org.apache.ignite.p2p.GridP2PJobClassLoaderSelfTest;
+import org.apache.ignite.p2p.GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest;
 import org.apache.ignite.p2p.GridP2PLocalDeploymentSelfTest;
 import org.apache.ignite.p2p.GridP2PMissedResourceCacheSizeSelfTest;
 import org.apache.ignite.p2p.GridP2PNodeLeftSelfTest;
@@ -66,6 +67,7 @@ import org.junit.runners.Suite;
     P2PScanQueryUndeployTest.class,
     GridDeploymentMessageCountSelfTest.class,
     GridP2PComputeWithNestedEntryProcessorTest.class,
+    GridP2PCountTiesLoadClassDirectlyFromClassLoaderTest.class
 })
 public class IgniteP2PSelfTestSuite {
 }