You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2020/07/10 15:37:55 UTC
[lucene-solr] 02/03: #48 Fix up XML resource sharing in tests
(threadlocal docbuilder) and add SysStats class for gather jvm load.
This is an automated email from the ASF dual-hosted git repository.
markrmiller pushed a commit to branch reference_impl
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
commit 7d9a0705f78a31ade8b6d1dfa070dba07fcf2505
Author: markrmiller@gmail.com <ma...@gmail.com>
AuthorDate: Fri Jul 10 09:13:17 2020 -0500
#48 Fix up XML resource sharing in tests (threadlocal docbuilder) and add SysStats class for gather jvm load.
---
.../org/apache/solr/core/SolrResourceLoader.java | 1 -
.../solr/rest/schema/FieldTypeXmlAdapter.java | 28 ++--
.../org/apache/solr/servlet/SolrQoSFilter.java | 28 +++-
.../java/org/apache/solr/util/SafeXMLParsing.java | 2 +-
.../org/apache/solr/BasicFunctionalityTest.java | 2 +-
.../org/apache/solr/TestDistributedGrouping.java | 71 +++++++--
.../solr/handler/admin/AdminHandlersProxyTest.java | 2 +
.../solr/handler/tagger/XmlInterpolationTest.java | 2 +-
.../solr/schema/TestUseDocValuesAsStored.java | 2 +-
.../search/TestLegacyNumericRangeQueryBuilder.java | 2 +-
.../org/apache/solr/update/AddBlockUpdateTest.java | 2 +-
.../src/java/org/apache/solr/common/ParWork.java | 5 +-
.../java/org/apache/solr/common/util/SysStats.java | 173 +++++++++++++++++++++
.../org/apache/solr/SolrIgnoredThreadsFilter.java | 4 +
.../java/org/apache/solr/util/DOMUtilTestBase.java | 2 +-
15 files changed, 290 insertions(+), 36 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
index 9013e38..c421af3 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
@@ -33,7 +33,6 @@ import java.nio.file.PathMatcher;
import java.nio.file.StandardOpenOption;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java b/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
index 41ee573..17afff8 100644
--- a/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
+++ b/solr/core/src/java/org/apache/solr/rest/schema/FieldTypeXmlAdapter.java
@@ -16,6 +16,7 @@
*/
package org.apache.solr.rest.schema;
+import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Map;
@@ -29,6 +30,8 @@ import org.apache.solr.common.params.CommonParams;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SimilarityFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -38,20 +41,27 @@ import org.w3c.dom.Node;
* XML format expected by the FieldTypePluginLoader.
*/
public class FieldTypeXmlAdapter {
-
- public static DocumentBuilder docBuilder;
-
- static {
- try {
- docBuilder = SolrResourceLoader.dbf.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- throw new SolrException(ErrorCode.SERVER_ERROR, e);
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ protected final static ThreadLocal<DocumentBuilder> THREAD_LOCAL_DB= new ThreadLocal<>();
+
+ public synchronized static DocumentBuilder getDocumentBuilder() {
+ DocumentBuilder db = THREAD_LOCAL_DB.get();
+ if (db == null) {
+ try {
+ db = SolrResourceLoader.dbf.newDocumentBuilder();
+ } catch (ParserConfigurationException e) {
+ log.error("Error in parser configuration", e);
+ throw new RuntimeException(e);
+ }
+ THREAD_LOCAL_DB.set(db);
}
+ return db;
}
public static Node toNode(Map<String,?> json) {
- Document doc = docBuilder.newDocument();
+ Document doc = getDocumentBuilder().newDocument();
Element fieldType = doc.createElement(IndexSchema.FIELD_TYPE);
appendAttrs(fieldType, json);
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrQoSFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrQoSFilter.java
index efb8afe..4bd44bd 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrQoSFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrQoSFilter.java
@@ -27,9 +27,8 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
-import net.sf.saxon.trans.Err;
-import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.QoSParams;
+import org.apache.solr.common.util.SysStats;
import org.eclipse.jetty.servlets.QoSFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,6 +42,9 @@ public class SolrQoSFilter extends QoSFilter {
static final int PROC_COUNT = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
protected int _origMaxRequests;
+
+ private static SysStats sysStats = SysStats.getSysStats();
+
@Override
public void init(FilterConfig filterConfig) {
super.init(filterConfig);
@@ -64,16 +66,26 @@ public class SolrQoSFilter extends QoSFilter {
log.warn("SystemLoadAverage not supported on this JVM");
load = 0;
}
- double sLoad = load / (double)PROC_COUNT;
- if (sLoad > 1.0D) {
+
+ double ourLoad = sysStats.getAvarageUsagePerCPU();
+ if (ourLoad > 1) {
int cMax = getMaxRequests();
if (cMax > 2) {
- setMaxRequests((int) ((double)cMax * 0.60D));
+ setMaxRequests(Math.max(1, (int) ((double)cMax * 0.60D)));
}
- } else if (sLoad < 0.9D &&_origMaxRequests != getMaxRequests()) {
- setMaxRequests(_origMaxRequests);
+ } else {
+ double sLoad = load / (double) PROC_COUNT;
+ if (sLoad > 1.0D) {
+ int cMax = getMaxRequests();
+ if (cMax > 2) {
+ setMaxRequests(Math.max(1, (int) ((double) cMax * 0.60D)));
+ }
+ } else if (sLoad < 0.9D && _origMaxRequests != getMaxRequests()) {
+ setMaxRequests(_origMaxRequests);
+ }
+ log.info("external request, load:" + sLoad); //nocommit: remove when testing is done
+
}
- log.info("external request, load:" + sLoad); //nocommit: remove when testing is done
super.doFilter(req, response, chain);
diff --git a/solr/core/src/java/org/apache/solr/util/SafeXMLParsing.java b/solr/core/src/java/org/apache/solr/util/SafeXMLParsing.java
index b89a68e..e1e9b74 100644
--- a/solr/core/src/java/org/apache/solr/util/SafeXMLParsing.java
+++ b/solr/core/src/java/org/apache/solr/util/SafeXMLParsing.java
@@ -54,7 +54,7 @@ public final class SafeXMLParsing {
/** Parses a config file from ResourceLoader. Xinclude and external entities are enabled, but cannot escape the resource loader. */
public static Document parseConfigXML(Logger log, ResourceLoader loader, String file) throws SAXException, IOException {
try (InputStream in = loader.openResource(file)) {
- final DocumentBuilder db = FieldTypeXmlAdapter.docBuilder;
+ final DocumentBuilder db = FieldTypeXmlAdapter.getDocumentBuilder();
return db.parse(in, SystemIdResolver.createSystemIdFromResourceName(file));
}
}
diff --git a/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java b/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
index 6b9a2f7..8b39b14 100644
--- a/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
+++ b/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
@@ -532,7 +532,7 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
SolrQueryRequest req = req("foo");
XMLWriter.writeResponse(writer,req,rsp);
- DocumentBuilder builder = FieldTypeXmlAdapter.docBuilder;
+ DocumentBuilder builder = FieldTypeXmlAdapter.getDocumentBuilder();
builder.parse(new ByteArrayInputStream
(writer.toString().getBytes(StandardCharsets.UTF_8)));
req.close();
diff --git a/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java b/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java
index 89eb343..043d884 100644
--- a/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java
+++ b/solr/core/src/test/org/apache/solr/TestDistributedGrouping.java
@@ -167,15 +167,68 @@ public class TestDistributedGrouping extends BaseDistributedSearchTestCase {
// test grouping
// The second sort = id asc . The sorting behaviour is different in dist mode. See TopDocs#merge
// The shard the result came from matters in the order if both document sortvalues are equal
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc");
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", 0, "sort", i1 + " asc, id asc");
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", "id asc, _docid_ asc");
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", "{!func}add(" + i1 + ",5) asc, id asc");
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "facet", "true", "facet.field", t1);
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "stats", "true", "stats.field", tlong);
- query("q", "kings", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "spellcheck", "true", "spellcheck.build", "true", "qt", "spellCheckCompRH", "df", "subject");
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "facet", "true", "hl","true","hl.fl",t1);
- query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "group.sort", "id desc");
+
+ try (ParWork worker = new ParWork(this)) {
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", "id asc, _docid_ asc");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", "{!func}add(" + i1 + ",5) asc, id asc");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "facet", "true", "facet.field", t1);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "stats", "true", "stats.field", tlong);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ worker.collect(() -> {
+ try {
+ query("q", "kings", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "spellcheck", "true", "spellcheck.build", "true", "qt", "spellCheckCompRH", "df", "subject");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "facet", "true", "hl","true","hl.fl",t1);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ worker.collect(() -> {
+ try {
+ query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.limit", -1, "sort", i1 + " asc, id asc", "group.sort", "id desc");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+ });
+ worker.addCollect("testQueries");
+ }
+
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "group.offset", 5, "group.limit", -1, "sort", i1 + " asc, id asc");
query("q", "*:*", "rows", 100, "fl", "id," + i1, "group", "true", "group.field", i1, "offset", 5, "rows", 5, "group.offset", 5, "group.limit", -1, "sort", i1 + " asc, id asc");
diff --git a/solr/core/src/test/org/apache/solr/handler/admin/AdminHandlersProxyTest.java b/solr/core/src/test/org/apache/solr/handler/admin/AdminHandlersProxyTest.java
index 6b426f9..958f3cb 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/AdminHandlersProxyTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/AdminHandlersProxyTest.java
@@ -39,6 +39,7 @@ import org.apache.solr.common.util.TimeSource;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
public class AdminHandlersProxyTest extends SolrCloudTestCase {
@@ -69,6 +70,7 @@ public class AdminHandlersProxyTest extends SolrCloudTestCase {
}
@Test
+ @Ignore // nocommit flakey
public void proxySystemInfoHandlerAllNodes() throws IOException, SolrServerException {
MapSolrParams params = new MapSolrParams(Collections.singletonMap("nodes", "all"));
GenericSolrRequest req = new GenericSolrRequest(SolrRequest.METHOD.GET, "/admin/info/system", params);
diff --git a/solr/core/src/test/org/apache/solr/handler/tagger/XmlInterpolationTest.java b/solr/core/src/test/org/apache/solr/handler/tagger/XmlInterpolationTest.java
index 2eaea2d..660d860 100644
--- a/solr/core/src/test/org/apache/solr/handler/tagger/XmlInterpolationTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/tagger/XmlInterpolationTest.java
@@ -52,7 +52,7 @@ public class XmlInterpolationTest extends TaggerTestCase {
@BeforeClass
public static void beforeClass() throws Exception {
- xmlDocBuilder = FieldTypeXmlAdapter.docBuilder;
+ xmlDocBuilder = FieldTypeXmlAdapter.getDocumentBuilder();
initCore("solrconfig-tagger.xml", "schema-tagger.xml");
}
diff --git a/solr/core/src/test/org/apache/solr/schema/TestUseDocValuesAsStored.java b/solr/core/src/test/org/apache/solr/schema/TestUseDocValuesAsStored.java
index c8c5c9c..8920b4a 100644
--- a/solr/core/src/test/org/apache/solr/schema/TestUseDocValuesAsStored.java
+++ b/solr/core/src/test/org/apache/solr/schema/TestUseDocValuesAsStored.java
@@ -74,7 +74,7 @@ public class TestUseDocValuesAsStored extends AbstractBadConfigTestBase {
END_RANDOM_EPOCH_MILLIS = LocalDateTime.of(11000, Month.DECEMBER, 31, 23, 59, 59, 999_000_000) // AD, 5 digit year
.toInstant(ZoneOffset.UTC).toEpochMilli();
try {
- DocumentBuilder builder = FieldTypeXmlAdapter.docBuilder;
+ DocumentBuilder builder = FieldTypeXmlAdapter.getDocumentBuilder();
InputStream stream = TestUseDocValuesAsStored.class.getResourceAsStream("/solr/collection1/conf/enumsConfig.xml");
Document doc = builder.parse(new InputSource(IOUtils.getDecodingReader(stream, StandardCharsets.UTF_8)));
XPath xpath = XmlConfigFile.xpath;
diff --git a/solr/core/src/test/org/apache/solr/search/TestLegacyNumericRangeQueryBuilder.java b/solr/core/src/test/org/apache/solr/search/TestLegacyNumericRangeQueryBuilder.java
index 05f363a..e3e3ead 100644
--- a/solr/core/src/test/org/apache/solr/search/TestLegacyNumericRangeQueryBuilder.java
+++ b/solr/core/src/test/org/apache/solr/search/TestLegacyNumericRangeQueryBuilder.java
@@ -168,7 +168,7 @@ public class TestLegacyNumericRangeQueryBuilder extends SolrTestCase {
private static Document getDocumentFromString(String str)
throws SAXException, IOException, ParserConfigurationException {
InputStream is = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
- DocumentBuilder builder = FieldTypeXmlAdapter.docBuilder;
+ DocumentBuilder builder = FieldTypeXmlAdapter.getDocumentBuilder();
Document doc = builder.parse(is);
is.close();
return doc;
diff --git a/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java b/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java
index 9af93f5..d28c65e 100644
--- a/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java
+++ b/solr/core/src/test/org/apache/solr/update/AddBlockUpdateTest.java
@@ -129,7 +129,7 @@ public class AddBlockUpdateTest extends SolrTestCaseJ4 {
}
private Document getDocument() throws ParserConfigurationException {
- javax.xml.parsers.DocumentBuilder docBuilder = FieldTypeXmlAdapter.docBuilder;
+ javax.xml.parsers.DocumentBuilder docBuilder = FieldTypeXmlAdapter.getDocumentBuilder();
return docBuilder.newDocument();
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/ParWork.java b/solr/solrj/src/java/org/apache/solr/common/ParWork.java
index 13d16c8..3947f25 100644
--- a/solr/solrj/src/java/org/apache/solr/common/ParWork.java
+++ b/solr/solrj/src/java/org/apache/solr/common/ParWork.java
@@ -43,6 +43,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.solr.client.solrj.impl.HttpClientUtil;
import org.apache.solr.common.util.OrderedExecutor;
+import org.apache.solr.common.util.SysStats;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,7 +69,7 @@ public class ParWork implements Closeable {
private Set<Object> collectSet = null;
- private static volatile ExecutorService executor;
+ private static SysStats sysStats = SysStats.getSysStats();
private static class WorkUnit {
private final List<Object> objects;
@@ -559,7 +560,7 @@ public class ParWork implements Closeable {
exec = getExecutorService(0, 30, 5);
THREAD_LOCAL_EXECUTOR.set(exec);
}
- // executor = exec;
+
return exec;
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/util/SysStats.java b/solr/solrj/src/java/org/apache/solr/common/util/SysStats.java
new file mode 100644
index 0000000..f63d7ba
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/common/util/SysStats.java
@@ -0,0 +1,173 @@
+package org.apache.solr.common.util;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.ThreadMXBean;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class SysStats extends Thread {
+ static final int PROC_COUNT = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
+
+ private long refreshInterval;
+ private boolean stopped;
+
+ private Map<Long, ThreadTime> threadTimeMap = new HashMap<Long, ThreadTime>(512);
+ private ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
+ private OperatingSystemMXBean opBean = ManagementFactory.getOperatingSystemMXBean();
+
+ private static SysStats sysStats;
+
+ public static synchronized SysStats getSysStats() {
+ if (sysStats == null) {
+ sysStats = new SysStats(5000);
+ }
+ return sysStats;
+ }
+
+ public SysStats(long refreshInterval) {
+ this.refreshInterval = refreshInterval;
+ setName("CPUMonitoringThread");
+ setDaemon(true);
+ start();
+ }
+
+ public void doStop() {
+ this.stopped = true;
+ }
+
+ @Override
+ public void run() {
+ while(!stopped) {
+ Set<Long> mappedIds;
+ synchronized (threadTimeMap) {
+ mappedIds = new HashSet<Long>(threadTimeMap.keySet());
+ }
+
+ long[] allThreadIds = threadBean.getAllThreadIds();
+
+ removeDeadThreads(mappedIds, allThreadIds);
+
+ mapNewThreads(allThreadIds);
+
+ Collection<ThreadTime> values;
+ synchronized (threadTimeMap) {
+ values = new HashSet<ThreadTime>(threadTimeMap.values());
+ }
+
+ for (ThreadTime threadTime : values) {
+ synchronized (threadTime) {
+ threadTime.setCurrent(threadBean.getThreadCpuTime(threadTime.getId()));
+ }
+ }
+
+ try {
+ Thread.sleep(refreshInterval);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+
+ for (ThreadTime threadTime : values) {
+ synchronized (threadTime) {
+ threadTime.setLast(threadTime.getCurrent());
+ }
+ }
+
+ }
+ }
+
+ private void mapNewThreads(long[] allThreadIds) {
+ for (long id : allThreadIds) {
+ synchronized (threadTimeMap) {
+ if(!threadTimeMap.containsKey(id))
+ threadTimeMap.put(id, new ThreadTime(id));
+ }
+ }
+ }
+
+ private void removeDeadThreads(Set<Long> mappedIds, long[] allThreadIds) {
+ outer: for (long id1 : mappedIds) {
+ for (long id2 : allThreadIds) {
+ if(id1 == id2)
+ continue outer;
+ }
+ synchronized (threadTimeMap) {
+ threadTimeMap.remove(id1);
+ }
+ }
+ }
+
+ public void stopMonitor() {
+ this.stopped = true;
+ }
+
+ public double getTotalUsage() {
+ Collection<ThreadTime> values;
+ synchronized (threadTimeMap) {
+ values = new HashSet<ThreadTime>(threadTimeMap.values());
+ }
+
+ double usage = 0D;
+ for (ThreadTime threadTime : values) {
+ synchronized (threadTime) {
+ usage += (threadTime.getCurrent() - threadTime.getLast()) / (refreshInterval * 10000);
+ }
+ }
+ return usage;
+ }
+
+ public double getAvarageUsagePerCPU() {
+ return getTotalUsage() / opBean.getAvailableProcessors();
+ }
+
+ public double getUsageByThread(Thread t) {
+ ThreadTime info;
+ synchronized (threadTimeMap) {
+ info = threadTimeMap.get(t.getId());
+ }
+
+ double usage = 0D;
+ if(info != null) {
+ synchronized (info) {
+ usage = (info.getCurrent() - info.getLast()) / (refreshInterval * 10000);
+ }
+ }
+ return usage;
+ }
+
+ static class ThreadTime {
+
+ private long id;
+ private long last;
+ private long current;
+
+ public ThreadTime(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public long getLast() {
+ return last;
+ }
+
+ public void setLast(long last) {
+ this.last = last;
+ }
+
+ public long getCurrent() {
+ return current;
+ }
+
+ public void setCurrent(long current) {
+ this.current = current;
+ }
+ }
+}
\ No newline at end of file
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java b/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java
index 6904986..1d925f8 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrIgnoredThreadsFilter.java
@@ -65,6 +65,10 @@ public class SolrIgnoredThreadsFilter implements ThreadFilter {
return true;
}
+ if (threadName.startsWith("CPUMonitoringThread")) { // zk thread that will stop in a moment.
+ return true;
+ }
+
if (threadName.startsWith("ParWork")) {
return true;
}
diff --git a/solr/test-framework/src/java/org/apache/solr/util/DOMUtilTestBase.java b/solr/test-framework/src/java/org/apache/solr/util/DOMUtilTestBase.java
index 05a0d39..dc4f56e 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/DOMUtilTestBase.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/DOMUtilTestBase.java
@@ -37,7 +37,7 @@ public abstract class DOMUtilTestBase extends SolrTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
- builder = FieldTypeXmlAdapter.docBuilder;
+ builder = FieldTypeXmlAdapter.getDocumentBuilder();
}
public Node getNode( String xml, String path ) throws Exception {