activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jbert...@apache.org
Subject [2/3] activemq-artemis git commit: ARTEMIS-684 Random is not equaly distributed among different VMs
Date Wed, 24 Aug 2016 15:32:08 GMT
ARTEMIS-684 Random is not equaly distributed among different VMs


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/92c5d5cd
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/92c5d5cd
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/92c5d5cd

Branch: refs/heads/master
Commit: 92c5d5cd50e8430ffa3aeb40736e4516128f7c24
Parents: 2bff3d2
Author: Clebert Suconic <clebertsuconic@apache.org>
Authored: Tue Aug 23 17:10:03 2016 -0400
Committer: Clebert Suconic <clebertsuconic@apache.org>
Committed: Tue Aug 23 19:36:54 2016 -0400

----------------------------------------------------------------------
 .../activemq/artemis/utils/RandomUtil.java      |   8 +-
 .../RandomConnectionLoadBalancingPolicy.java    |   6 +-
 ...ndomStickyConnectionLoadBalancingPolicy.java |   6 +-
 ...RoundRobinConnectionLoadBalancingPolicy.java |   6 +-
 .../apache/activemq/artemis/utils/Random.java   |  39 -------
 .../core/util/RandomUtilDistributionTest.java   | 102 +++++++++++++++++++
 .../artemis/tests/unit/util/UTF8Test.java       |   7 +-
 7 files changed, 116 insertions(+), 58 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
----------------------------------------------------------------------
diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
index 0451437..8aabd1b 100644
--- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
+++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/RandomUtil.java
@@ -26,7 +26,11 @@ import org.apache.activemq.artemis.api.core.SimpleString;
 public class RandomUtil {
    // Constants -----------------------------------------------------
 
-   protected static final Random random = new Random(System.currentTimeMillis());
+   protected static final Random random = new Random();
+
+   public static Random getRandom() {
+      return random;
+   }
 
    // Attributes ----------------------------------------------------
 
@@ -75,7 +79,7 @@ public class RandomUtil {
    }
 
    public static int randomInterval(final int min, final int max) {
-      return min + randomMax(max - min);
+      return min + random.nextInt(max - min);
    }
 
    public static int randomMax(final int max) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomConnectionLoadBalancingPolicy.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomConnectionLoadBalancingPolicy.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomConnectionLoadBalancingPolicy.java
index 4ab66a3..e411c9c 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomConnectionLoadBalancingPolicy.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomConnectionLoadBalancingPolicy.java
@@ -16,7 +16,7 @@
  */
 package org.apache.activemq.artemis.api.core.client.loadbalance;
 
-import org.apache.activemq.artemis.utils.Random;
+import org.apache.activemq.artemis.utils.RandomUtil;
 
 /**
  * {@link RandomConnectionLoadBalancingPolicy#select(int)} returns a (pseudo) random integer
between
@@ -24,8 +24,6 @@ import org.apache.activemq.artemis.utils.Random;
  */
 public final class RandomConnectionLoadBalancingPolicy implements ConnectionLoadBalancingPolicy
{
 
-   private final Random random = new Random();
-
    /**
     * Returns a pseudo random number between {@code 0} (inclusive) and {@code max} exclusive.
     *
@@ -34,6 +32,6 @@ public final class RandomConnectionLoadBalancingPolicy implements ConnectionLoad
     */
    @Override
    public int select(final int max) {
-      return random.getRandom().nextInt(max);
+      return RandomUtil.randomInterval(0, max);
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomStickyConnectionLoadBalancingPolicy.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomStickyConnectionLoadBalancingPolicy.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomStickyConnectionLoadBalancingPolicy.java
index 5e269a9..12c59fd 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomStickyConnectionLoadBalancingPolicy.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RandomStickyConnectionLoadBalancingPolicy.java
@@ -16,15 +16,13 @@
  */
 package org.apache.activemq.artemis.api.core.client.loadbalance;
 
-import org.apache.activemq.artemis.utils.Random;
+import org.apache.activemq.artemis.utils.RandomUtil;
 
 /**
  * {@link RandomConnectionLoadBalancingPolicy#select(int)} chooses a the initial node randomly
then subsequent requests return the same node
  */
 public final class RandomStickyConnectionLoadBalancingPolicy implements ConnectionLoadBalancingPolicy
{
 
-   private final Random random = new Random();
-
    private int pos = -1;
 
    /**
@@ -33,7 +31,7 @@ public final class RandomStickyConnectionLoadBalancingPolicy implements
Connecti
    @Override
    public int select(final int max) {
       if (pos == -1) {
-         pos = random.getRandom().nextInt(max);
+         pos = RandomUtil.randomInterval(0, max);
       }
 
       return pos;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RoundRobinConnectionLoadBalancingPolicy.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RoundRobinConnectionLoadBalancingPolicy.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RoundRobinConnectionLoadBalancingPolicy.java
index cdf0828..58694b6 100644
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RoundRobinConnectionLoadBalancingPolicy.java
+++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/client/loadbalance/RoundRobinConnectionLoadBalancingPolicy.java
@@ -18,7 +18,7 @@ package org.apache.activemq.artemis.api.core.client.loadbalance;
 
 import java.io.Serializable;
 
-import org.apache.activemq.artemis.utils.Random;
+import org.apache.activemq.artemis.utils.RandomUtil;
 
 /**
  * RoundRobinConnectionLoadBalancingPolicy corresponds to a round-robin load-balancing policy.
@@ -31,8 +31,6 @@ public final class RoundRobinConnectionLoadBalancingPolicy implements Connection
 
    private static final long serialVersionUID = 7511196010141439559L;
 
-   private final Random random = new Random();
-
    private boolean first = true;
 
    private int pos;
@@ -41,7 +39,7 @@ public final class RoundRobinConnectionLoadBalancingPolicy implements Connection
    public int select(final int max) {
       if (first) {
          // We start on a random one
-         pos = random.getRandom().nextInt(max);
+         pos = RandomUtil.randomInterval(0, max);
 
          first = false;
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/Random.java
----------------------------------------------------------------------
diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/Random.java
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/Random.java
deleted file mode 100644
index b93fd7e..0000000
--- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/utils/Random.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.activemq.artemis.utils;
-
-import java.io.Serializable;
-
-public class Random implements Serializable {
-
-   private static int extraSeed;
-
-   private static final long serialVersionUID = 40335522290950498L;
-
-   private static synchronized long getSeed() {
-      long seed = System.currentTimeMillis() + Random.extraSeed++;
-
-      return seed;
-   }
-
-   private final java.util.Random random = new java.util.Random(Random.getSeed());
-
-   public java.util.Random getRandom() {
-      return random;
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilDistributionTest.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilDistributionTest.java
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilDistributionTest.java
new file mode 100644
index 0000000..68b348a
--- /dev/null
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/util/RandomUtilDistributionTest.java
@@ -0,0 +1,102 @@
+/**
+ * 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.activemq.artemis.tests.unit.core.util;
+
+
+import java.util.HashSet;
+
+import org.apache.activemq.artemis.tests.util.SpawnedVMSupport;
+import org.apache.activemq.artemis.utils.RandomUtil;
+import org.junit.Assert;
+import org.junit.Test;
+
+/** This test will start many parallel VMs, to make sure each VM would generate a good distribution
of random numbers */
+public class RandomUtilDistributionTest {
+   public static void main(String[] arg) {
+
+      long start = Long.parseLong(arg[0]);
+
+      try {
+         Thread.sleep((start - System.currentTimeMillis()) / 2);
+      }
+      catch (Exception e) {
+      }
+      while (System.currentTimeMillis() < start) {
+         Thread.yield();
+      }
+      int value;
+      value = RandomUtil.randomInterval(0, 255);
+      System.exit(value);
+   }
+
+   @Test
+   public void testDistribution() throws Exception {
+      int numberOfStarts = 50;
+      int iterations = 10;
+
+      int value = 0;
+      for (int i = 0; i < iterations; i++) {
+
+         int v = internalDistributionTest(numberOfStarts);
+
+         value += v;
+      }
+
+      // I'm using an extra parenthesis here to avoid rounding problems.
+      // Be careful removing it (make sure you know what you're doing in case you do so)
+      int minimumExpected = (int)((iterations * numberOfStarts) * 0.80);
+
+      System.out.println("value=" + value + ", minimum expected = " + minimumExpected);
+      Assert.assertTrue("The Random distribution is pretty bad. All tries have returned duplicated
randoms. value=" + value + ", minimum expected = " + minimumExpected, value > minimumExpected);
+
+   }
+
+   private int internalDistributionTest(int numberOfTries) throws Exception {
+      long timeStart = System.currentTimeMillis() + 5000;
+      Process[] process = new Process[numberOfTries];
+      int[] value = new int[numberOfTries];
+      try {
+         for (int i = 0; i < numberOfTries; i++) {
+            process[i] = SpawnedVMSupport.spawnVM(RandomUtilDistributionTest.class.getName(),
true, "" + timeStart);
+         }
+
+
+         HashSet<Integer> valueSet = new HashSet<>();
+
+         for (int i = 0; i < numberOfTries; i++) {
+            value[i] = process[i].waitFor();
+            Assert.assertTrue(value[i] >= 0);
+            valueSet.add(process[i].exitValue());
+         }
+
+         System.out.println("Generated " + valueSet.size() + " randoms out of  " + numberOfTries
+ " tries");
+
+         return valueSet.size();
+
+
+      }
+      finally {
+         for (Process p : process) {
+            if (p != null) {
+               p.destroy();
+            }
+         }
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/92c5d5cd/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/UTF8Test.java
----------------------------------------------------------------------
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/UTF8Test.java
b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/UTF8Test.java
index 26c5e9d..ffaf6aa 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/UTF8Test.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/UTF8Test.java
@@ -32,7 +32,6 @@ import java.nio.ByteBuffer;
 import org.junit.Assert;
 
 import org.apache.activemq.artemis.utils.DataConstants;
-import org.apache.activemq.artemis.utils.Random;
 import org.apache.activemq.artemis.utils.RandomUtil;
 import org.apache.activemq.artemis.utils.UTF8Util;
 
@@ -44,8 +43,7 @@ public class UTF8Test extends ActiveMQTestBase {
 
       byte[] bytes = new byte[20000];
 
-      Random random = new Random();
-      random.getRandom().nextBytes(bytes);
+      RandomUtil.getRandom().nextBytes(bytes);
 
       String str = new String(bytes);
 
@@ -59,12 +57,11 @@ public class UTF8Test extends ActiveMQTestBase {
    @Test
    public void testValidateUTFOnDataInput() throws Exception {
       for (int i = 0; i < 100; i++) {
-         Random random = new Random();
 
          // Random size between 15k and 20K
          byte[] bytes = new byte[15000 + RandomUtil.randomPositiveInt() % 5000];
 
-         random.getRandom().nextBytes(bytes);
+         RandomUtil.getRandom().nextBytes(bytes);
 
          String str = new String(bytes);
 


Mime
View raw message