diff --git a/core/src/main/java/org/infinispan/cache/impl/CacheImpl.java b/core/src/main/java/org/infinispan/cache/impl/CacheImpl.java index 2f70a68295c6..1684c9e7d8ee 100644 --- a/core/src/main/java/org/infinispan/cache/impl/CacheImpl.java +++ b/core/src/main/java/org/infinispan/cache/impl/CacheImpl.java @@ -65,6 +65,7 @@ import org.infinispan.commons.util.Version; import org.infinispan.configuration.cache.Configuration; import org.infinispan.configuration.cache.Configurations; +import org.infinispan.configuration.cache.ExpirationConfiguration; import org.infinispan.configuration.format.PropertyFormatter; import org.infinispan.configuration.global.GlobalConfiguration; import org.infinispan.container.DataContainer; @@ -177,7 +178,7 @@ public class CacheImpl implements AdvancedCache, InternalCache @Inject ComponentRef encoderCache; @Inject GroupManager groupManager; - protected Metadata defaultMetadata; + protected volatile Metadata defaultMetadata; private final String name; private volatile boolean stopping = false; private boolean transactional; @@ -196,11 +197,18 @@ public CacheImpl(String name) { public void preStart() { // We have to do this before start, since some components may start before the actual cache and they // have to have access to the default metadata on some operations - defaultMetadata = Configurations.newDefaultMetadata(config); + updateDefaultMetadata(); + // Listen for changes to the defaults + config.expiration().attributes().attribute(ExpirationConfiguration.LIFESPAN).addListener((attribute, oldValue) -> updateDefaultMetadata()); + config.expiration().attributes().attribute(ExpirationConfiguration.MAX_IDLE).addListener((attribute, oldValue) -> updateDefaultMetadata()); transactional = config.transaction().transactionMode().isTransactional(); batchingEnabled = config.invocationBatching().enabled(); } + private void updateDefaultMetadata() { + defaultMetadata = Configurations.newDefaultMetadata(config); + } + @Override public ComponentRegistry getComponentRegistry() { return componentRegistry; diff --git a/core/src/test/java/org/infinispan/api/MetadataAPIDefaultExpiryTest.java b/core/src/test/java/org/infinispan/api/MetadataAPIDefaultExpiryTest.java index 3aea9163bec1..e9482935009c 100644 --- a/core/src/test/java/org/infinispan/api/MetadataAPIDefaultExpiryTest.java +++ b/core/src/test/java/org/infinispan/api/MetadataAPIDefaultExpiryTest.java @@ -6,14 +6,16 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.infinispan.commons.time.ControlledTimeService; +import org.infinispan.commons.time.TimeService; import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.configuration.cache.ExpirationConfiguration; +import org.infinispan.container.entries.CacheEntry; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.metadata.EmbeddedMetadata; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; -import org.infinispan.commons.time.ControlledTimeService; -import org.infinispan.commons.time.TimeService; import org.testng.annotations.Test; @Test(groups = "functional", testName = "api.MetadataAPIDefaultExpiryTest") @@ -80,6 +82,23 @@ public void testDefaultLifespanPutAsync() throws Exception { expectCachedThenExpired(2, "v2"); } + public void updateExpiration() { + cache().put(1, "value"); + CacheEntry entry = cache().getAdvancedCache().getCacheEntry(1); + assertEquals(EXPIRATION_TIMEOUT, entry.getLifespan()); + assertEquals(-1, entry.getMaxIdle()); + cache().getCacheConfiguration().expiration().attributes().attribute(ExpirationConfiguration.LIFESPAN).set(EXPIRATION_TIMEOUT * 2L); + cache().put(2, "value"); + entry = cache().getAdvancedCache().getCacheEntry(2); + assertEquals(EXPIRATION_TIMEOUT * 2, entry.getLifespan()); + assertEquals(-1, entry.getMaxIdle()); + cache().getCacheConfiguration().expiration().attributes().attribute(ExpirationConfiguration.MAX_IDLE).set(EXPIRATION_TIMEOUT * 3L); + cache().put(3, "value"); + entry = cache().getAdvancedCache().getCacheEntry(3); + assertEquals(EXPIRATION_TIMEOUT * 2, entry.getLifespan()); + assertEquals(EXPIRATION_TIMEOUT * 3, entry.getMaxIdle()); + } + private void expectCachedThenExpired(Integer key, String value) { // Check that it doesn't expire too early controlledTimeService.advance(EXPIRATION_TIMEOUT - 1); diff --git a/core/src/test/java/org/infinispan/expiry/ExpiryTest.java b/core/src/test/java/org/infinispan/expiry/ExpiryTest.java index 0001af5dcdb6..3fd74443ff56 100644 --- a/core/src/test/java/org/infinispan/expiry/ExpiryTest.java +++ b/core/src/test/java/org/infinispan/expiry/ExpiryTest.java @@ -17,6 +17,7 @@ import org.infinispan.Cache; import org.infinispan.commons.test.CommonsTestingUtil; +import org.infinispan.commons.time.ControlledTimeService; import org.infinispan.commons.time.TimeService; import org.infinispan.commons.util.Util; import org.infinispan.configuration.cache.ConfigurationBuilder; @@ -27,7 +28,6 @@ import org.infinispan.test.AbstractInfinispanTest; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; -import org.infinispan.commons.time.ControlledTimeService; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -37,7 +37,6 @@ public class ExpiryTest extends AbstractInfinispanTest { public static final int EXPIRATION_TIMEOUT = 3000; public static final int IDLE_TIMEOUT = 3000; - public static final int EXPIRATION_CHECK_TIMEOUT = 2000; CacheContainer cm; protected ControlledTimeService timeService; @@ -374,7 +373,6 @@ private void doValuesAfterExpiryInTransaction(Method m, CacheContainer cc) throw // Values come as a Collection, but comparison of HashMap#Values is done // by reference equality, so wrap the collection around to set to make // testing easier, given that we know that there are dup values. - Collection values; Map dataIn = new HashMap<>(); dataIn.put(1, v(m, 1)); dataIn.put(2, v(m, 2));