From 7ac22c374fa1029b9ac1252eb4f1053762095796 Mon Sep 17 00:00:00 2001 From: Vladimir Buhtoyarov Date: Mon, 29 Apr 2024 14:42:58 +0300 Subject: [PATCH] #461 support flexible expiration for Infinispan --- README.md | 4 ++-- .../bucket4j/grid/infinispan/Bucket4jInfinispan.java | 5 +++++ .../bucket4j/grid/infinispan/InfinispanProcessor.java | 10 +++++++++- .../grid/infinispan/InfinispanProxyManager.java | 5 +++++ .../bucket4j/grid/infinispan/InfinispanTest.java | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 458bed88..a738ef36 100644 --- a/README.md +++ b/README.md @@ -77,12 +77,12 @@ Its key advantage lies in the configuration via properties or yaml files, elimin ### Supported JCache compatible(or similar) back-ends In addition to local in-memory buckets, the Bucket4j supports clustered usage scenario on top of following back-ends: -| Back-end | Async supported | Flexible per-entry expiration | Optimized serialization | Thin-client support | Documentation link | +| Back-end | Async supported | Flexible per-entry expiration | Optimized serialization | Thin-client support | Documentation link | | :--- | :---: |:-----------------------------:|:-----------------------:|:-------------------:|:-------------------------------------------------------------------------------------:| | ```JCache API (JSR 107)``` | No | No | No | No | [bucket4j-jcache](https://bucket4j.github.io/8.12.0/toc.html#bucket4j-jcache) | | ```Hazelcast``` | Yes | Yes | Yes | No | [bucket4j-hazelcast](https://bucket4j.github.io/8.12.0/toc.html#bucket4j-hazelcast) | | ```Apache Ignite``` | Yes | No | n/a | Yes | [bucket4j-ignite](https://bucket4j.github.io/8.12.0/toc.html#bucket4j-ignite) | -| ```Inifinispan``` | Yes | TODO | Yes | No | [bucket4j-infinispan](https://bucket4j.github.io/8.12.0/toc.html#bucket4j-infinispan) | +| ```Inifinispan``` | Yes | Yes | Yes | No | [bucket4j-infinispan](https://bucket4j.github.io/8.12.0/toc.html#bucket4j-infinispan) | | ```Oracle Coherence``` | Yes | Yes | Yes | No | [bucket4j-coherence](https://bucket4j.github.io/8.12.0/toc.html#bucket4j-coherence) | ### Redis back-ends diff --git a/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/Bucket4jInfinispan.java b/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/Bucket4jInfinispan.java index 41827351..e51d4919 100644 --- a/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/Bucket4jInfinispan.java +++ b/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/Bucket4jInfinispan.java @@ -57,6 +57,11 @@ public InfinispanProxyManager build() { return new InfinispanProxyManager<>(this); } + @Override + public boolean isExpireAfterWriteSupported() { + return true; + } + } } diff --git a/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProcessor.java b/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProcessor.java index 53e1fbc9..8c7b4be3 100644 --- a/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProcessor.java +++ b/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProcessor.java @@ -21,12 +21,14 @@ import java.io.Serial; +import io.github.bucket4j.distributed.ExpirationAfterWriteStrategy; import io.github.bucket4j.distributed.remote.AbstractBinaryTransaction; import io.github.bucket4j.distributed.remote.RemoteBucketState; import io.github.bucket4j.distributed.remote.Request; import io.github.bucket4j.distributed.serialization.InternalSerializationHelper; import io.github.bucket4j.util.ComparableByContent; import org.infinispan.functional.EntryView; +import org.infinispan.functional.MetaParam; import org.infinispan.util.function.SerializableFunction; public class InfinispanProcessor implements @@ -69,7 +71,13 @@ protected byte[] getRawState() { @Override protected void setRawState(byte[] newStateBytes, RemoteBucketState newState) { - entry.set(newStateBytes); + ExpirationAfterWriteStrategy expirationStrategy = getExpirationStrategy(); + long ttlMillis = expirationStrategy == null ? -1 : expirationStrategy.calculateTimeToLiveMillis(newState, getCurrentTimeNanos()); + if (ttlMillis > 0) { + entry.set(newStateBytes, new MetaParam.MetaLifespan(ttlMillis)); + } else { + entry.set(newStateBytes); + } } }.execute(); } diff --git a/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProxyManager.java b/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProxyManager.java index 033572b7..e455048b 100644 --- a/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProxyManager.java +++ b/bucket4j-infinispan-all/bucket4j-infinispan/src/main/java/io/github/bucket4j/grid/infinispan/InfinispanProxyManager.java @@ -127,4 +127,9 @@ public CompletableFuture> executeAsync(K key, Request re } } + @Override + public boolean isExpireAfterWriteSupported() { + return true; + } + } diff --git a/bucket4j-infinispan-all/bucket4j-infinispan/src/test/java/io/github/bucket4j/grid/infinispan/InfinispanTest.java b/bucket4j-infinispan-all/bucket4j-infinispan/src/test/java/io/github/bucket4j/grid/infinispan/InfinispanTest.java index 023dbe1a..3d1b80ef 100644 --- a/bucket4j-infinispan-all/bucket4j-infinispan/src/test/java/io/github/bucket4j/grid/infinispan/InfinispanTest.java +++ b/bucket4j-infinispan-all/bucket4j-infinispan/src/test/java/io/github/bucket4j/grid/infinispan/InfinispanTest.java @@ -61,7 +61,7 @@ public static void init() throws MalformedURLException, URISyntaxException { "InfinispanProxyManager", () -> UUID.randomUUID().toString(), () -> Bucket4jInfinispan.entryProcessorBasedBuilder(readWriteMap) - ) + ).checkExpiration() ); }