Skip to content

Commit 79992d8

Browse files
committed
HTTPCLIENT-2406: MemcachedHttpCacheStorage to support per entry expiry setting
1 parent 919dfe0 commit 79992d8

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingCacheStorage.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*/
2727
package org.apache.hc.client5.http.impl.cache;
2828

29+
import java.time.Instant;
2930
import java.util.ArrayList;
3031
import java.util.Collection;
3132
import java.util.HashMap;
@@ -60,6 +61,13 @@ public AbstractSerializingCacheStorage(final int maxUpdateRetries, final HttpCac
6061

6162
protected abstract void store(String storageKey, T storageObject) throws ResourceIOException;
6263

64+
/**
65+
* @since 5.6
66+
*/
67+
protected void store(final String storageKey, final Instant expectedExpiry, final T storageObject) throws ResourceIOException {
68+
store(storageKey, storageObject);
69+
}
70+
6371
protected abstract T restore(String storageKey) throws ResourceIOException;
6472

6573
protected abstract CAS getForUpdateCAS(String storageKey) throws ResourceIOException;
@@ -76,7 +84,8 @@ public AbstractSerializingCacheStorage(final int maxUpdateRetries, final HttpCac
7684
public final void putEntry(final String key, final HttpCacheEntry entry) throws ResourceIOException {
7785
final String storageKey = digestToStorageKey(key);
7886
final T storageObject = serializer.serialize(new HttpCacheStorageEntry(key, entry));
79-
store(storageKey, storageObject);
87+
final Instant expires = entry.getExpires();
88+
store(storageKey, expires, storageObject);
8089
}
8190

8291
@Override

httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpCacheStorage.java

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,26 @@
2828

2929
import java.io.IOException;
3030
import java.net.InetSocketAddress;
31+
import java.time.Duration;
32+
import java.time.Instant;
3133
import java.util.Collection;
3234
import java.util.HashMap;
3335
import java.util.Map;
3436
import java.util.concurrent.CancellationException;
37+
import java.util.function.BiFunction;
3538

39+
import net.spy.memcached.CASResponse;
40+
import net.spy.memcached.CASValue;
41+
import net.spy.memcached.MemcachedClient;
42+
import net.spy.memcached.MemcachedClientIF;
43+
import net.spy.memcached.OperationTimeoutException;
3644
import org.apache.hc.client5.http.cache.HttpCacheEntrySerializer;
3745
import org.apache.hc.client5.http.cache.ResourceIOException;
3846
import org.apache.hc.client5.http.impl.cache.AbstractBinaryCacheStorage;
3947
import org.apache.hc.client5.http.impl.cache.CacheConfig;
4048
import org.apache.hc.client5.http.impl.cache.HttpByteArrayCacheEntrySerializer;
4149
import org.apache.hc.core5.util.Args;
4250

43-
import net.spy.memcached.CASResponse;
44-
import net.spy.memcached.CASValue;
45-
import net.spy.memcached.MemcachedClient;
46-
import net.spy.memcached.MemcachedClientIF;
47-
import net.spy.memcached.OperationTimeoutException;
48-
4951
/**
5052
* <p>
5153
* This class is a storage backend that uses an external <i>memcached</i>
@@ -88,6 +90,7 @@ public class MemcachedHttpCacheStorage extends AbstractBinaryCacheStorage<CASVal
8890

8991
private final MemcachedClientIF client;
9092
private final KeyHashingScheme keyHashingScheme;
93+
private final BiFunction<String, Instant, Duration> expiryResolver;
9194

9295
/**
9396
* Create a storage backend talking to a <i>memcached</i> instance
@@ -119,7 +122,7 @@ public MemcachedHttpCacheStorage(final MemcachedClient cache) {
119122
* @since 5.2
120123
*/
121124
public MemcachedHttpCacheStorage(final MemcachedClientIF cache) {
122-
this(cache, CacheConfig.DEFAULT, HttpByteArrayCacheEntrySerializer.INSTANCE, SHA256KeyHashingScheme.INSTANCE);
125+
this(cache, CacheConfig.DEFAULT, HttpByteArrayCacheEntrySerializer.INSTANCE, SHA256KeyHashingScheme.INSTANCE, null);
123126
}
124127

125128
/**
@@ -137,7 +140,18 @@ public MemcachedHttpCacheStorage(
137140
final CacheConfig config,
138141
final HttpCacheEntrySerializer<byte[]> serializer,
139142
final KeyHashingScheme keyHashingScheme) {
140-
this((MemcachedClientIF) client, config, serializer, keyHashingScheme);
143+
this(client, config, serializer, keyHashingScheme, null);
144+
}
145+
146+
/**
147+
* @since 5.2
148+
*/
149+
public MemcachedHttpCacheStorage(
150+
final MemcachedClientIF client,
151+
final CacheConfig config,
152+
final HttpCacheEntrySerializer<byte[]> serializer,
153+
final KeyHashingScheme keyHashingScheme) {
154+
this(client, config, serializer, keyHashingScheme, null);
141155
}
142156

143157
/**
@@ -150,17 +164,20 @@ public MemcachedHttpCacheStorage(
150164
* @param serializer alternative serialization mechanism
151165
* @param keyHashingScheme how to map higher-level logical "storage keys"
152166
* onto "cache keys" suitable for use with memcached
153-
* @since 5.2
167+
* @param expiryResolver resolver for cache entry expiry
168+
* @since 5.6
154169
*/
155170
public MemcachedHttpCacheStorage(
156171
final MemcachedClientIF client,
157172
final CacheConfig config,
158173
final HttpCacheEntrySerializer<byte[]> serializer,
159-
final KeyHashingScheme keyHashingScheme) {
174+
final KeyHashingScheme keyHashingScheme,
175+
final BiFunction<String, Instant, Duration> expiryResolver) {
160176
super((config != null ? config : CacheConfig.DEFAULT).getMaxUpdateRetries(),
161177
serializer != null ? serializer : HttpByteArrayCacheEntrySerializer.INSTANCE);
162178
this.client = Args.notNull(client, "Memcached client");
163179
this.keyHashingScheme = keyHashingScheme;
180+
this.expiryResolver = expiryResolver;
164181
}
165182

166183
@Override
@@ -170,8 +187,21 @@ protected String digestToStorageKey(final String key) {
170187

171188
@Override
172189
protected void store(final String storageKey, final byte[] storageObject) throws ResourceIOException {
190+
store(storageKey, null, storageObject);
191+
}
192+
193+
@Override
194+
protected void store(final String storageKey, final Instant expectedExpiry, final byte[] storageObject) throws ResourceIOException {
195+
int exp = 0;
196+
final Duration validityduration = expiryResolver != null ? expiryResolver.apply(storageKey, expectedExpiry) : null;
197+
if (validityduration != null) {
198+
final long expSeconds = validityduration.getSeconds();
199+
if (expSeconds > 0) {
200+
exp = (int) expSeconds;
201+
}
202+
}
173203
try {
174-
client.set(storageKey, 0, storageObject);
204+
client.set(storageKey, exp, storageObject);
175205
} catch (final CancellationException ex) {
176206
throw new MemcachedOperationCancellationException(ex);
177207
}

0 commit comments

Comments
 (0)