This is an automated email from the ASF dual-hosted git repository. eshu11 pushed a commit to branch feature/GEODE-5173 in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/feature/GEODE-5173 by this push: new 8644df6 GEODE-5173: Transaction will fault in value from disk if value is Token.NOT_AVAILABLE. 8644df6 is described below commit 8644df61dc5c062fbca45517e407c5ad8dff15db Author: eshu <e...@pivotal.io> AuthorDate: Fri May 4 11:53:40 2018 -0700 GEODE-5173: Transaction will fault in value from disk if value is Token.NOT_AVAILABLE. --- .../geode/internal/cache/InternalRegion.java | 2 +- .../apache/geode/internal/cache/LocalRegion.java | 22 +-- .../PersistentRegionTransactionDUnitTest.java | 210 +++++++++++++++++++++ 3 files changed, 220 insertions(+), 14 deletions(-) diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java index 7633713..db931cc 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/InternalRegion.java @@ -313,7 +313,7 @@ public interface InternalRegion extends Region, HasCachePerfStats, RegionEntryCo void setInUseByTransaction(boolean b); - void txLRUStart(); + boolean txLRUStart(); void txLRUEnd(); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java index 420948c..c099160 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java @@ -8334,19 +8334,15 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory, try { synchronized (regionEntry) { if (!regionEntry.isRemoved()) { - if (regionEntry instanceof DiskEntry && regionEntry instanceof EvictableEntry) { - EvictableEntry le = (EvictableEntry) regionEntry; - if (le.isEvicted()) { - // Handle the case where we fault in a disk entry - txLRUStart(); - needsLRUCleanup = true; - - // Fault in the value from disk - regionEntry.getValue(this); - } + Object value = regionEntry.getValueInVM(this); + if (value == Token.NOT_AVAILABLE) { + // Entry value is on disk + // Handle the case where we fault in a evicted disk entry + needsLRUCleanup = txLRUStart(); + // Fault in the value from disk + value = regionEntry.getValue(this); } - Object value = regionEntry.getValueInVM(this); /* * The tx will need the raw value for identity comparison. Please see * TXEntryState#checkForConflict(LocalRegion,Object) @@ -8446,8 +8442,8 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory, } @Override - public void txLRUStart() { - this.entries.disableLruUpdateCallback(); + public boolean txLRUStart() { + return this.entries.disableLruUpdateCallback(); } @Override diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/PersistentRegionTransactionDUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/PersistentRegionTransactionDUnitTest.java new file mode 100644 index 0000000..b2a7d44 --- /dev/null +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/PersistentRegionTransactionDUnitTest.java @@ -0,0 +1,210 @@ +/* + * 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.internal.cache; + +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import java.util.stream.IntStream; + +import org.awaitility.Awaitility; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.CacheFactory; +import org.apache.geode.cache.EvictionAction; +import org.apache.geode.cache.EvictionAttributes; +import org.apache.geode.cache.RegionShortcut; +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.cache.server.CacheServer; +import org.apache.geode.test.dunit.VM; +import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase; +import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties; + +public class PersistentRegionTransactionDUnitTest extends JUnit4CacheTestCase { + + private VM server; + private VM client; + private final int KEY = 5; + private final String VALUE = "value 5"; + private final String REGIONNAME = "region"; + + @Rule + public DistributedRestoreSystemProperties restoreSystemProperties = + new DistributedRestoreSystemProperties(); + + + @Before + public void allowTransactions() { + server = VM.getVM(-1); + client = VM.getVM(1); + server.invoke(() -> TXManagerImpl.ALLOW_PERSISTENT_TRANSACTIONS = true); + } + + @After + public void disallowTransactions() { + server.invoke(() -> TXManagerImpl.ALLOW_PERSISTENT_TRANSACTIONS = false); + + } + + @Test + public void testClientTransactionWorksOnRecoveredPersistentOverflowRegion() throws Exception { + createServer(server, true); + + putData(server); + server.invoke(() -> getCache().close()); + int port = createServer(server, true); + + + client.invoke(() -> { + ClientCacheFactory factory = new ClientCacheFactory().addPoolServer("localhost", port); + ClientCache cache = getClientCache(factory); + cache.getCacheTransactionManager().begin(); + try { + assertEquals(VALUE, cache.createClientRegionFactory(ClientRegionShortcut.PROXY) + .create(REGIONNAME).get(KEY)); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } + + private void putData(final VM server) { + server.invoke(() -> { + IntStream.range(0, 20) + .forEach(index -> getCache().getRegion(REGIONNAME).put(index, "value " + index)); + }); + } + + private int createServer(final VM server, boolean isOverflow) { + return server.invoke(() -> { + if (!isOverflow) { + System.setProperty(DiskStoreImpl.RECOVER_VALUE_PROPERTY_NAME, "false"); + } + CacheFactory cacheFactory = new CacheFactory(); + Cache cache = getCache(cacheFactory); + if (isOverflow) { + cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT) + .setEvictionAttributes( + EvictionAttributes.createLRUEntryAttributes(1, EvictionAction.OVERFLOW_TO_DISK)) + .create(REGIONNAME); + } else { + cache.createRegionFactory(RegionShortcut.REPLICATE_PERSISTENT).create(REGIONNAME); + } + CacheServer cacheServer = cache.addCacheServer(); + cacheServer.start(); + return cacheServer.getPort(); + }); + } + + @Test + public void testClientTransactionWorksOnPersistentOverflowRegion() throws Exception { + int port = createServer(server, true); + putData(server); + + client.invoke(() -> { + ClientCacheFactory factory = new ClientCacheFactory().addPoolServer("localhost", port); + ClientCache cache = getClientCache(factory); + cache.getCacheTransactionManager().begin(); + try { + assertEquals(VALUE, cache.createClientRegionFactory(ClientRegionShortcut.PROXY) + .create(REGIONNAME).get(KEY)); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } + + @Test + public void testTransactionWorksOnPersistentOverflowRegion() throws Exception { + createServer(server, true); + putData(server); + + server.invoke(() -> { + LocalRegion region = (LocalRegion) getCache().getRegion(REGIONNAME); + Awaitility.await().atMost(10, SECONDS) + .until(() -> assertThat(region.getValueInVM(KEY)).isNull()); + getCache().getCacheTransactionManager().begin(); + try { + assertEquals(VALUE, region.get(KEY)); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } + + @Test + public void testTransactionWorksOnRecoveredPersistentOverflowRegion() throws Exception { + createServer(server, true); + putData(server); + server.invoke(() -> getCache().close()); + createServer(server, true); + server.invoke(() -> { + LocalRegion region = (LocalRegion) getCache().getRegion("region"); + getCache().getCacheTransactionManager().begin(); + try { + assertEquals(VALUE, region.get(KEY)); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } + + @Test + public void testTransactionWorksOnRecoveredPersistentRegion() throws Exception { + createServer(server, false); + putData(server); + server.invoke(() -> getCache().close()); + createServer(server, false); + server.invoke(() -> { + LocalRegion region = (LocalRegion) getCache().getRegion("region"); + assertThat(region.getValueInVM(KEY)).isNull(); + getCache().getCacheTransactionManager().begin(); + try { + assertEquals(VALUE, region.get(KEY)); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } + + @Test + public void testClientTransactionWorksOnRecoveredPersistentRegion() throws Exception { + createServer(server, false); + + putData(server); + server.invoke(() -> getCache().close()); + int port = createServer(server, false); + + + client.invoke(() -> { + ClientCacheFactory factory = new ClientCacheFactory().addPoolServer("localhost", port); + ClientCache cache = getClientCache(factory); + cache.getCacheTransactionManager().begin(); + try { + assertEquals(VALUE, cache.createClientRegionFactory(ClientRegionShortcut.PROXY) + .create(REGIONNAME).get(KEY)); + } finally { + cache.getCacheTransactionManager().rollback(); + } + }); + } +} -- To stop receiving notification emails like this one, please contact esh...@apache.org.