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");
+ }
+}