You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2020/08/18 16:16:32 UTC
[geode] branch develop updated: GEODE-8425: Add new stats for
handling netsearch
This is an automated email from the ASF dual-hosted git repository.
klund pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new 28790ca GEODE-8425: Add new stats for handling netsearch
28790ca is described below
commit 28790ca86d977d97ab224ec4118ea2a0c1e2a763
Author: Kirk Lund <kl...@apache.org>
AuthorDate: Thu Aug 6 10:51:54 2020 -0700
GEODE-8425: Add new stats for handling netsearch
---
.../ReplicateRegionNetsearchDistributedTest.java | 545 +++++++++++++++++++++
.../geode/internal/cache/CachePerfStats.java | 75 ++-
.../cache/SearchLoadAndWriteProcessor.java | 12 +-
.../geode/internal/cache/CachePerfStatsTest.java | 109 ++++-
.../geode/test/dunit/rules/DistributedRule.java | 5 +
5 files changed, 742 insertions(+), 4 deletions(-)
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache/ReplicateRegionNetsearchDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache/ReplicateRegionNetsearchDistributedTest.java
new file mode 100644
index 0000000..e9a6ed3
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/cache/ReplicateRegionNetsearchDistributedTest.java
@@ -0,0 +1,545 @@
+/*
+ * 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.geode.cache;
+
+import static org.apache.geode.cache.EvictionAttributes.createLRUEntryAttributes;
+import static org.apache.geode.distributed.ConfigurationProperties.ENABLE_CLUSTER_CONFIGURATION;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.internal.util.ArrayUtils.asList;
+import static org.apache.geode.test.dunit.VM.getVM;
+import static org.apache.geode.test.dunit.rules.DistributedRule.getLocatorPort;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientCacheFactory;
+import org.apache.geode.cache.client.ClientRegionShortcut;
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.internal.cache.CachePerfStats;
+import org.apache.geode.internal.cache.InternalRegion;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedReference;
+import org.apache.geode.test.dunit.rules.DistributedRule;
+import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
+
+@SuppressWarnings("serial")
+public class ReplicateRegionNetsearchDistributedTest implements Serializable {
+
+ private static final String REPLICATE_1_NAME = "replicate1";
+ private static final String REPLICATE_2_NAME = "replicate2";
+ private static final String PROXY_NAME = "proxy";
+ private static final String REGION_NAME = "region";
+
+ private VM replicate1;
+ private VM replicate2;
+ private VM proxy;
+ private VM client;
+
+ private File replicate1Dir;
+ private File replicate2Dir;
+ private File proxyDir;
+
+ @Rule
+ public DistributedRule distributedRule = new DistributedRule();
+ @Rule
+ public DistributedReference<ServerLauncher> serverLauncher = new DistributedReference<>();
+ @Rule
+ public DistributedReference<ClientCache> clientCache = new DistributedReference<>();
+ @Rule
+ public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder();
+
+ @Before
+ public void setUp() throws Exception {
+ replicate1 = getVM(0);
+ replicate2 = getVM(1);
+ proxy = getVM(2);
+ client = getVM(3);
+
+ replicate1Dir = temporaryFolder.newFolder(REPLICATE_1_NAME);
+ replicate2Dir = temporaryFolder.newFolder(REPLICATE_2_NAME);
+ proxyDir = temporaryFolder.newFolder(PROXY_NAME);
+
+ int locatorPort = getLocatorPort();
+
+ replicate1.invoke(() -> {
+ serverLauncher.set(startServer(REPLICATE_1_NAME, replicate1Dir, locatorPort));
+ });
+ replicate2.invoke(() -> {
+ serverLauncher.set(startServer(REPLICATE_2_NAME, replicate2Dir, locatorPort));
+ });
+ proxy.invoke(() -> {
+ serverLauncher.set(startServer(PROXY_NAME, proxyDir, locatorPort));
+ });
+ }
+
+ @Test
+ public void proxyReplicateDoesNetsearchFromFullReplicate() {
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+
+ region.put("key-1", "value-1");
+ });
+
+ proxy.invoke(() -> {
+ serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE_PROXY)
+ .create(REGION_NAME);
+ });
+
+ proxy.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+
+ String value = region.get("key-1");
+
+ assertThat(value).isEqualTo("value-1");
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(region.getAttributes().getPartitionAttributes()).isNull();
+ });
+ }
+
+ @Test
+ public void fullReplicateDoesNotPerformNetsearch() {
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+
+ region.put("key-1", "value-1");
+ });
+
+ proxy.invoke(() -> {
+ serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE_PROXY)
+ .create(REGION_NAME);
+ });
+
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+
+ String value = region.get("key-1");
+
+ assertThat(value).isEqualTo("value-1");
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ });
+ }
+
+ @Test
+ public void replicateWithExpirationDoesNetsearchOnMiss() {
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+
+ region.put("key-1", "value-1");
+ region.put("key-2", "value-2");
+ });
+
+ replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .setEvictionAttributes(createLRUEntryAttributes(1))
+ .create(REGION_NAME);
+
+ assertThat(region).hasSize(1);
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+
+ assertThat(region).hasSize(1);
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+
+ String value = region.get("key-1");
+
+ assertThat(value).isEqualTo("value-1");
+
+ assertThat(region).hasSize(1);
+
+ assertThat(regionPerfStats.getGets()).isOne();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+
+ assertThat(region).hasSize(1);
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isOne();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+
+ String value = region.get("key-1");
+
+ assertThat(value).isEqualTo("value-1");
+
+ assertThat(region).hasSize(1);
+
+ assertThat(regionPerfStats.getGets()).isEqualTo(2);
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+
+ assertThat(region).hasSize(1);
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isEqualTo(2);
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+
+ String value = region.get("key-2");
+
+ assertThat(value).isEqualTo("value-2");
+
+ assertThat(region).hasSize(1);
+
+ assertThat(regionPerfStats.getGets()).isEqualTo(3);
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isEqualTo(2);
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isEqualTo(2);
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isEqualTo(2);
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+ }
+
+ @Test
+ public void proxyReplicateDoesNetsearchFromOnlyOneFullReplicate() {
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+
+ region.put("key-1", "value-1");
+ region.put("key-2", "value-2");
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ proxy.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE_PROXY)
+ .create(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ for (VM vm : asList(replicate1, replicate2)) {
+ vm.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+ }
+
+ proxy.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+
+ assertThat(region.get("key-1")).isEqualTo("value-1");
+
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ long handlingNetsearchesCompletedInReplicate1 = replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+ return regionPerfStats.getHandlingNetsearchesCompleted();
+ });
+
+ long handlingNetsearchesCompletedInReplicate2 = replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+ return regionPerfStats.getHandlingNetsearchesCompleted();
+ });
+
+ // only one replicate should have been used to handle the netsearch
+ assertThat(handlingNetsearchesCompletedInReplicate1 + handlingNetsearchesCompletedInReplicate2)
+ .isOne();
+
+ proxy.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+ }
+
+ @Test
+ public void clientGetFromProxyReplicateDoesNetsearchFromFullReplicate() {
+ replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+
+ region.put("key-1", "value-1");
+ });
+
+ replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE)
+ .create(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isOne();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ int proxyServerPort = proxy.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache()
+ .<String, String>createRegionFactory(RegionShortcut.REPLICATE_PROXY)
+ .create(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+
+ return serverLauncher.get().getCache().getCacheServers().get(0).getPort();
+ });
+
+ client.invoke(() -> {
+ clientCache.set(new ClientCacheFactory()
+ .addPoolServer("localhost", proxyServerPort)
+ .create());
+ Region<String, String> region = clientCache.get()
+ .<String, String>createClientRegionFactory(ClientRegionShortcut.PROXY)
+ .create(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getGetInitialImagesCompleted()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ for (VM vm : asList(replicate1, replicate2, proxy)) {
+ vm.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+ }
+
+ client.invoke(() -> {
+ Region<String, String> region = clientCache.get().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(region.get("key-1")).isEqualTo("value-1");
+
+ assertThat(regionPerfStats.getGets()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+
+ for (VM vm : asList(replicate1, replicate2)) {
+ vm.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isZero();
+ assertThat(regionPerfStats.getMisses()).isZero();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+ }
+
+ long handlingNetsearchesCompletedInReplicate1 = replicate1.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+ return regionPerfStats.getHandlingNetsearchesCompleted();
+ });
+
+ long handlingNetsearchesCompletedInReplicate2 = replicate2.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+ return regionPerfStats.getHandlingNetsearchesCompleted();
+ });
+
+ // only one replicate should have been used to handle the netsearch
+ assertThat(handlingNetsearchesCompletedInReplicate1 + handlingNetsearchesCompletedInReplicate2)
+ .isOne();
+
+ proxy.invoke(() -> {
+ Region<String, String> region = serverLauncher.get().getCache().getRegion(REGION_NAME);
+ CachePerfStats regionPerfStats = getRegionPerfStats(region);
+
+ assertThat(regionPerfStats.getGets()).isOne();
+ assertThat(regionPerfStats.getMisses()).isOne();
+ assertThat(regionPerfStats.getNetsearchesCompleted()).isOne();
+ assertThat(regionPerfStats.getHandlingNetsearchesCompleted()).isZero();
+ assertThat(regionPerfStats.getHandlingNetsearchesFailed()).isZero();
+ });
+ }
+
+ private ServerLauncher startServer(String serverName, File serverDir, int locatorPort) {
+ ServerLauncher serverLauncher = new ServerLauncher.Builder()
+ .setMemberName(serverName)
+ .setWorkingDirectory(serverDir.getAbsolutePath())
+ .setServerPort(0)
+ .set(LOCATORS, "localHost[" + locatorPort + "]")
+ .set(ENABLE_CLUSTER_CONFIGURATION, "false")
+ .build();
+
+ serverLauncher.start();
+
+ return serverLauncher;
+ }
+
+ private CachePerfStats getRegionPerfStats(Region<?, ?> region) {
+ return ((InternalRegion) region).getRegionPerfStats();
+ }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java b/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java
index 7371ec0..5bbca52 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/CachePerfStats.java
@@ -21,6 +21,7 @@ import org.apache.geode.StatisticsFactory;
import org.apache.geode.StatisticsType;
import org.apache.geode.StatisticsTypeFactory;
import org.apache.geode.annotations.Immutable;
+import org.apache.geode.annotations.VisibleForTesting;
import org.apache.geode.distributed.internal.PoolStatHelper;
import org.apache.geode.distributed.internal.QueueStatHelper;
import org.apache.geode.internal.NanoTimer;
@@ -155,6 +156,17 @@ public class CachePerfStats {
static final int compressionPreCompressedBytesId;
static final int compressionPostCompressedBytesId;
+ @VisibleForTesting
+ static final int handlingNetsearchesInProgressId;
+ @VisibleForTesting
+ static final int handlingNetsearchesCompletedId;
+ @VisibleForTesting
+ static final int handlingNetsearchesTimeId;
+ @VisibleForTesting
+ static final int handlingNetsearchesFailedId;
+ @VisibleForTesting
+ static final int handlingNetsearchesFailedTimeId;
+
static {
StatisticsTypeFactory f = StatisticsTypeFactoryImpl.singleton();
@@ -332,6 +344,17 @@ public class CachePerfStats {
final String evictByCriteria_evaluationTimeDesc =
"Total time taken for evaluation of user expression during eviction";
+ final String handlingNetsearchesInProgressDesc =
+ "Current number of threads handling a network search initiated by a remote cache.";
+ final String handlingNetsearchesCompletedDesc =
+ "Total number of times handling a network search initiated by a remote cache completed with success.";
+ final String handlingNetsearchesTimeDesc =
+ "Total time spent handling successful network searches for remote caches.";
+ final String handlingNetsearchesFailedDesc =
+ "Total number of times handling a network search initiated by a remote cache failed without success.";
+ final String handlingNetsearchesFailedTimeDesc =
+ "Total time spent handling failed network searches for remote caches.";
+
type = f.createType("CachePerfStats", "Statistics about GemFire cache performance",
new StatisticDescriptor[] {
f.createIntGauge("loadsInProgress", loadsInProgressDesc, "operations"),
@@ -491,7 +514,19 @@ public class CachePerfStats {
f.createLongCounter("evictByCriteria_evaluations", evictByCriteria_evaluationsDesc,
"operations"),
f.createLongCounter("evictByCriteria_evaluationTime",
- evictByCriteria_evaluationTimeDesc, "nanoseconds")});
+ evictByCriteria_evaluationTimeDesc, "nanoseconds"),
+
+ f.createLongGauge("handlingNetsearchesInProgress", handlingNetsearchesInProgressDesc,
+ "operations"),
+ f.createLongCounter("handlingNetsearchesCompleted", handlingNetsearchesCompletedDesc,
+ "operations"),
+ f.createLongCounter("handlingNetsearchesTime", handlingNetsearchesTimeDesc,
+ "nanoseconds"),
+ f.createLongCounter("handlingNetsearchesFailed", handlingNetsearchesFailedDesc,
+ "operations"),
+ f.createLongCounter("handlingNetsearchesFailedTime", handlingNetsearchesFailedTimeDesc,
+ "nanoseconds")
+ });
loadsInProgressId = type.nameToId("loadsInProgress");
loadsCompletedId = type.nameToId("loadsCompleted");
@@ -612,6 +647,12 @@ public class CachePerfStats {
compressionDecompressionsId = type.nameToId("decompressions");
compressionPreCompressedBytesId = type.nameToId("preCompressedBytes");
compressionPostCompressedBytesId = type.nameToId("postCompressedBytes");
+
+ handlingNetsearchesInProgressId = type.nameToId("handlingNetsearchesInProgress");
+ handlingNetsearchesCompletedId = type.nameToId("handlingNetsearchesCompleted");
+ handlingNetsearchesTimeId = type.nameToId("handlingNetsearchesTime");
+ handlingNetsearchesFailedId = type.nameToId("handlingNetsearchesFailed");
+ handlingNetsearchesFailedTimeId = type.nameToId("handlingNetsearchesFailedTime");
}
/** The Statistics object that we delegate most behavior to */
@@ -1449,4 +1490,36 @@ public class CachePerfStats {
stats.incLong(exportTimeId, getTime() - start);
}
}
+
+ /**
+ * @return the timestamp that marks the start of the operation
+ */
+ public long startHandlingNetsearch() {
+ stats.incLong(handlingNetsearchesInProgressId, 1);
+ return getTime();
+ }
+
+ /**
+ * @param start the timestamp taken when the operation started
+ * @param success true if handling the netsearch was successful
+ */
+ public void endHandlingNetsearch(long start, boolean success) {
+ long ts = getTime();
+ if (success) {
+ stats.incLong(handlingNetsearchesCompletedId, 1);
+ stats.incLong(handlingNetsearchesTimeId, ts - start);
+ } else {
+ stats.incLong(handlingNetsearchesFailedId, 1);
+ stats.incLong(handlingNetsearchesFailedTimeId, ts - start);
+ }
+ stats.incLong(handlingNetsearchesInProgressId, -1);
+ }
+
+ public long getHandlingNetsearchesCompleted() {
+ return stats.getLong(handlingNetsearchesCompletedId);
+ }
+
+ public long getHandlingNetsearchesFailed() {
+ return stats.getLong(handlingNetsearchesFailedId);
+ }
}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/SearchLoadAndWriteProcessor.java b/geode-core/src/main/java/org/apache/geode/internal/cache/SearchLoadAndWriteProcessor.java
index 1a5e3de..f9e8b73 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/SearchLoadAndWriteProcessor.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/SearchLoadAndWriteProcessor.java
@@ -1866,10 +1866,16 @@ public class SearchLoadAndWriteProcessor implements MembershipListener {
boolean authoritative = false;
VersionTag versionTag = null;
+ InternalCache cache = dm.getExistingCache();
+
final InitializationLevel oldLevel =
LocalRegion.setThreadInitLevelRequirement(BEFORE_INITIAL_IMAGE);
+ LocalRegion region = (LocalRegion) cache.getRegion(this.regionName);
+ CachePerfStats stats =
+ region == null ? cache.getCachePerfStats() : region.getRegionPerfStats();
+ long startHandlingTime = stats.startHandlingNetsearch();
+ boolean handlingSuccess = false;
try {
- LocalRegion region = (LocalRegion) dm.getExistingCache().getRegion(this.regionName);
if (region != null) {
setClearCountReference(region);
try {
@@ -1883,7 +1889,7 @@ public class SearchLoadAndWriteProcessor implements MembershipListener {
versionTag = versionStamp.asVersionTag();
}
Object eov = region.getNoLRU(this.key, false, true, true); // OFFHEAP: incrc, copy
- // bytes, decrc
+ // bytes, decrc
if (eov != null) {
if (eov == Token.INVALID || eov == Token.LOCAL_INVALID) {
// nothing?
@@ -1916,6 +1922,7 @@ public class SearchLoadAndWriteProcessor implements MembershipListener {
ebvLen = ebv.length;
}
}
+ handlingSuccess = true;
} else {
requestorTimedOut = true;
}
@@ -1953,6 +1960,7 @@ public class SearchLoadAndWriteProcessor implements MembershipListener {
replyWithNull(dm);
} finally {
LocalRegion.setThreadInitLevelRequirement(oldLevel);
+ stats.endHandlingNetsearch(startHandlingTime, handlingSuccess);
}
}
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java
index ef96053..7a81fdd 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/CachePerfStatsTest.java
@@ -32,6 +32,11 @@ import static org.apache.geode.internal.cache.CachePerfStats.evictorJobsStartedI
import static org.apache.geode.internal.cache.CachePerfStats.getInitialImagesCompletedId;
import static org.apache.geode.internal.cache.CachePerfStats.getTimeId;
import static org.apache.geode.internal.cache.CachePerfStats.getsId;
+import static org.apache.geode.internal.cache.CachePerfStats.handlingNetsearchesCompletedId;
+import static org.apache.geode.internal.cache.CachePerfStats.handlingNetsearchesFailedId;
+import static org.apache.geode.internal.cache.CachePerfStats.handlingNetsearchesFailedTimeId;
+import static org.apache.geode.internal.cache.CachePerfStats.handlingNetsearchesInProgressId;
+import static org.apache.geode.internal.cache.CachePerfStats.handlingNetsearchesTimeId;
import static org.apache.geode.internal.cache.CachePerfStats.indexUpdateCompletedId;
import static org.apache.geode.internal.cache.CachePerfStats.invalidatesId;
import static org.apache.geode.internal.cache.CachePerfStats.loadsCompletedId;
@@ -52,6 +57,7 @@ import static org.apache.geode.internal.cache.CachePerfStats.txRollbackChangesId
import static org.apache.geode.internal.cache.CachePerfStats.txRollbacksId;
import static org.apache.geode.internal.cache.CachePerfStats.updatesId;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -62,6 +68,7 @@ import org.junit.Test;
import org.apache.geode.Statistics;
import org.apache.geode.StatisticsFactory;
import org.apache.geode.StatisticsType;
+import org.apache.geode.internal.statistics.StatisticsClock;
import org.apache.geode.internal.statistics.StatisticsManager;
import org.apache.geode.internal.statistics.StripedStatisticsImpl;
@@ -74,6 +81,7 @@ public class CachePerfStatsTest {
private static final long CLOCK_TIME = 10;
private Statistics statistics;
+ private StatisticsClock statisticsClock;
private CachePerfStats cachePerfStats;
@Before
@@ -84,11 +92,16 @@ public class CachePerfStatsTest {
StatisticsFactory statisticsFactory = mock(StatisticsFactory.class);
statistics = new StripedStatisticsImpl(statisticsType, TEXT_ID, 1, 1, statisticsManager);
+ statisticsClock = mock(StatisticsClock.class);
+ when(statisticsClock.isEnabled())
+ .thenReturn(true);
+ when(statisticsClock.getTime())
+ .thenReturn(CLOCK_TIME);
when(statisticsFactory.createAtomicStatistics(eq(statisticsType), eq(TEXT_ID)))
.thenReturn(statistics);
- cachePerfStats = new CachePerfStats(statisticsFactory, TEXT_ID, () -> CLOCK_TIME);
+ cachePerfStats = new CachePerfStats(statisticsFactory, TEXT_ID, statisticsClock);
}
@Test
@@ -1132,4 +1145,98 @@ public class CachePerfStatsTest {
assertThat(statistics.getLong(entryCountId)).isEqualTo(-2);
}
+
+ @Test
+ public void handlingNetsearchesInProgressIsZeroByDefault() {
+ assertThat(statistics.getLong(handlingNetsearchesInProgressId)).isZero();
+ }
+
+ @Test
+ public void handlingNetsearchesCompletedIsZeroByDefault() {
+ assertThat(statistics.getLong(handlingNetsearchesCompletedId)).isZero();
+ }
+
+ @Test
+ public void handlingNetsearchesTimeIsZeroByDefault() {
+ assertThat(statistics.getLong(handlingNetsearchesTimeId)).isZero();
+ }
+
+ @Test
+ public void handlingNetsearchesFailedIsZeroByDefault() {
+ assertThat(statistics.getLong(handlingNetsearchesFailedId)).isZero();
+ }
+
+ @Test
+ public void handlingNetsearchesFailedTimeIsZeroByDefault() {
+ assertThat(statistics.getLong(handlingNetsearchesFailedTimeId)).isZero();
+ }
+
+ @Test
+ public void startHandlingNetsearchIncreasesHandlingNetsearchesInProgress() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+
+ cachePerfStats.startHandlingNetsearch();
+
+ assertThat(statistics.getLong(handlingNetsearchesInProgressId)).isOne();
+ }
+
+ @Test
+ public void endHandlingNetsearchIncreasesHandlingNetsearchesCompletedIfSuccess() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+ long startTime = cachePerfStats.startHandlingNetsearch();
+
+ cachePerfStats.endHandlingNetsearch(startTime, true);
+
+ assertThat(statistics.getLong(handlingNetsearchesCompletedId)).isOne();
+ }
+
+ @Test
+ public void endHandlingNetsearchIncreasesHandlingNetsearchesTimeIfSuccess() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+ long startTime = cachePerfStats.startHandlingNetsearch();
+
+ cachePerfStats.endHandlingNetsearch(startTime, true);
+
+ assertThat(statistics.getLong(handlingNetsearchesTimeId)).isEqualTo(9);
+ }
+
+ @Test
+ public void endHandlingNetsearchIncreasesHandlingNetsearchesFailedIfNotSuccess() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+ long startTime = cachePerfStats.startHandlingNetsearch();
+
+ cachePerfStats.endHandlingNetsearch(startTime, false);
+
+ assertThat(statistics.getLong(handlingNetsearchesFailedId)).isOne();
+ }
+
+ @Test
+ public void endHandlingNetsearchIncreasesHandlingNetsearchesFailedTimeIfNotSuccess() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+ long startTime = cachePerfStats.startHandlingNetsearch();
+
+ cachePerfStats.endHandlingNetsearch(startTime, false);
+
+ assertThat(statistics.getLong(handlingNetsearchesFailedTimeId)).isEqualTo(9);
+ }
+
+ @Test
+ public void endHandlingNetsearchDecreasesHandlingNetsearchesInProgressIfSuccess() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+ long startTime = cachePerfStats.startHandlingNetsearch();
+
+ cachePerfStats.endHandlingNetsearch(startTime, true);
+
+ assertThat(statistics.getLong(handlingNetsearchesInProgressId)).isZero();
+ }
+
+ @Test
+ public void endHandlingNetsearchDecreasesHandlingNetsearchesInProgressIfNotSuccess() {
+ doReturn(1L, 10L).when(statisticsClock).getTime();
+ long startTime = cachePerfStats.startHandlingNetsearch();
+
+ cachePerfStats.endHandlingNetsearch(startTime, false);
+
+ assertThat(statistics.getLong(handlingNetsearchesInProgressId)).isZero();
+ }
}
diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java
index 1943fcd..84872dc 100644
--- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java
+++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java
@@ -40,6 +40,7 @@ import org.apache.geode.internal.net.SocketCreator;
import org.apache.geode.internal.net.SocketCreatorFactory;
import org.apache.geode.management.internal.cli.LogWrapper;
import org.apache.geode.pdx.internal.TypeRegistry;
+import org.apache.geode.test.dunit.DistributedTestUtils;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.internal.DUnitLauncher;
import org.apache.geode.test.junit.rules.serializable.SerializableExternalResource;
@@ -152,6 +153,10 @@ public class DistributedRule extends AbstractDistributedRule {
return DUnitLauncher.getDistributedSystemProperties();
}
+ public static int getLocatorPort() {
+ return DistributedTestUtils.getLocatorPort();
+ }
+
/**
* Builds an instance of DistributedRule.
*/