You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2015/03/09 20:49:47 UTC

svn commit: r1665331 - in /uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImpl.java test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImplTest.java

Author: schor
Date: Mon Mar  9 19:49:46 2015
New Revision: 1665331

URL: http://svn.apache.org/r1665331
Log: (empty)

Added:
    uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImplTest.java
Modified:
    uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImpl.java

Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImpl.java?rev=1665331&r1=1665330&r2=1665331&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImpl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImpl.java Mon Mar  9 19:49:46 2015
@@ -21,15 +21,16 @@ package org.apache.uima.analysis_engine.
 
 import java.text.DecimalFormat;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
 
 import org.apache.uima.UimaContextAdmin;
 import org.apache.uima.analysis_engine.AnalysisEngineManagement;
+import org.apache.uima.util.ConcurrentHashMapWithProducer;
 
 /**
  * Implements Monitoring/Management interface to an AnalysisEngine.
@@ -48,7 +49,7 @@ public class AnalysisEngineManagementImp
    * This static set is needed to keep track of what names we've already used for "root" MBeans
    * (those representing top-level AEs and CPEs).
    */
-  private static Set<String> usedRootNames = new HashSet<String>();
+  private static ConcurrentHashMapWithProducer<String, AtomicInteger> usedRootNames = new ConcurrentHashMapWithProducer<String, AtomicInteger>();
 
   private String name;
 
@@ -255,7 +256,7 @@ public class AnalysisEngineManagementImp
       prefix = aCustomPrefix;
       if (!prefix.endsWith(":") && !prefix.endsWith(",")) {
         prefix += ",";
-}
+      }
     }
     // compute the unique name   
     // (first get the rootMBean and assign it a unique name if it doesn't already have one)
@@ -263,18 +264,8 @@ public class AnalysisEngineManagementImp
             .getRootContext().getManagementInterface();
     if (rootMBean.getUniqueMBeanName() == null) {
       // try to find a unique name for the root MBean
-      String baseRootName = rootMBean.getName();
-      if (baseRootName == null) {
-        baseRootName = "CPE"; // CPE's don't currently have names
-      }
-      String rootName = baseRootName;
-      int i = 2;
-      while (usedRootNames.contains(rootName)) {
-        rootName = baseRootName + " " + i++;
-      }
-      usedRootNames.add(rootName);
-      // create a propertly-formatted MBean name, using the specified prefix
-      rootMBean.uniqueMBeanName = prefix + "name=" + escapeValue(rootName);
+      String rootName = getRootName(rootMBean.getName());
+      rootMBean.uniqueMBeanName = prefix + "name=" + escapeValue(getRootName(rootMBean.getName()));
     }
 
     if (rootMBean != this) {
@@ -294,6 +285,28 @@ public class AnalysisEngineManagementImp
       uniqueMBeanName = makeMBeanName(prefix, aContext.getQualifiedContextName().substring(1), 1);
     }
   }
+  
+  static private final Callable<AtomicInteger> produceAtomicInteger = new Callable<AtomicInteger>() {  
+    @Override
+    public AtomicInteger call() throws Exception{
+      return new AtomicInteger(1);
+    }
+  };
+  
+  // package private for testing
+  static String getRootName(String baseRootName) {
+    if (baseRootName == null) {
+      baseRootName = "CPE"; // CPE's don't currently have names
+    }
+    AtomicInteger suffix;
+    try {
+      suffix = usedRootNames.get(baseRootName, produceAtomicInteger);
+    } catch (Exception e) {
+      throw new RuntimeException(e); // never happen.
+    }
+    int suffixI = suffix.getAndIncrement();
+    return (suffixI == 1) ? baseRootName : baseRootName + suffixI;
+  }
 
   /**
    * Recursive utility method for generating a hierarchical mbean name

Added: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImplTest.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImplTest.java?rev=1665331&view=auto
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImplTest.java (added)
+++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineManagementImplTest.java Mon Mar  9 19:49:46 2015
@@ -0,0 +1,65 @@
+/*
+ * 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.uima.analysis_engine.impl;
+
+import java.util.Collections;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.internal.util.MultiThreadUtils;
+
+import junit.framework.TestCase;
+
+public class AnalysisEngineManagementImplTest extends TestCase {
+
+  public void testNameGenerate() throws Exception {
+    assertEquals("foo", AnalysisEngineManagementImpl.getRootName("foo"));
+    assertEquals("foo2", AnalysisEngineManagementImpl.getRootName("foo"));
+    assertEquals("foo3", AnalysisEngineManagementImpl.getRootName("foo"));
+    
+    // Try multi-threaded
+    final Random random = new Random();
+    final Set<String> s = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
+    int numberOfThreads = Math.min(50, MultiThreadUtils.PROCESSORS * 5); 
+
+    MultiThreadUtils.Run2isb run2isb = new MultiThreadUtils.Run2isb() {
+
+      //  This method is run 100 * # of threads 
+      //  It gets a root name based on "bar" - each one should get another name
+      //   Tested by adding to a concurrent set and verifying it wasn't there before.
+      public void call(int threadNbr, int repeatNbr, StringBuilder sb) throws Exception {
+//        Random random = new Random();
+        for (int j = 0; j < 2; j++) {
+          assertTrue(s.add(AnalysisEngineManagementImpl.getRootName("bar")));
+//          Thread.sleep(10, random.nextInt(2000));
+          if ((threadNbr % 2) == 0) {
+            Thread.sleep(0, random.nextInt(2000));  // sleep for 2 microseconds
+          }
+        }
+      }
+    };
+    
+    System.out.format("test multicore AnalysisEngineManagementImpl getRootName with %d threads%n", numberOfThreads);
+
+    MultiThreadUtils.tstMultiThread("UniqueRootNameGenerator",  numberOfThreads,  100, run2isb, null);
+//    System.out.println("debug");
+  }
+}