in evcache-core/src/main/java/com/netflix/evcache/EVCache.java [867:1512]
<T> Map<String, T> getBulkAndTouch(Collection<String> keys, Transcoder<T> tc, int timeToLive)
throws EVCacheException;
/**
* Get the value for given key asynchronously and deserialize it with the
* default transcoder.
*
* @param key
* the key for which we need the value. Ensure the key is
* properly encoded and does not contain whitespace or control
* characters. The max length of the key (including prefix)
* is 200 characters.
* @return the Futures containing the Value or null.
* @throws EVCacheException
* in the circumstance where queue is too full to accept any
* more requests or issues during deserialization or timeout
* retrieving the value or any IO Related issues
*
* @deprecated This is a sub-optimal operation does not support Retries, Fast Failures, FIT, GC Detection, etc.
* Will be removed in a subsequent release
*/
<T> Future<T> getAsynchronous(String key) throws EVCacheException;
/**
* Get the value for given key asynchronously and deserialize it with the
* given transcoder.
*
* @param key
* the key for which we need the value. Ensure the key is
* properly encoded and does not contain whitespace or control
* characters. The max length of the key (including prefix)
* is 200 characters.
* @param tc
* the transcoder to use for deserialization
* @return the Futures containing the Value or null.
* @throws EVCacheException
* in the circumstance where queue is too full to accept any
* more requests or issues during deserialization or timeout
* retrieving the value or any IO Related issues
*
* @deprecated This is a sub-optimal operation does not support Retries, Fast Failures, FIT, GC Detection, etc.
* Will be removed in a subsequent release
*/
<T> Future<T> getAsynchronous(String key, Transcoder<T> tc) throws EVCacheException;
/**
* Increment the given counter, returning the new value.
*
* @param key
* the key. Ensure the key is
* properly encoded and does not contain whitespace or control
* characters. The max length of the key (including prefix)
* is 200 characters.
* @param by
* the amount to increment
* @param def
* the default value (if the counter does not exist)
* @param exp
* the expiration of this object
* @return the new value, or -1 if we were unable to increment or add
* @throws EVCacheException
* in the circumstance where timeout is exceeded or queue is
* full
*
*/
public long incr(String key, long by, long def, int exp) throws EVCacheException;
/**
* Decrement the given counter, returning the new value.
*
* @param key
* the key. Ensure the key is
* properly encoded and does not contain whitespace or control
* characters. The max length of the key (including prefix)
* is 200 characters.
* @param by
* the amount to decrement
* @param def
* the default value (if the counter does not exist)
* @param exp
* the expiration of this object
* @return the new value, or -1 if we were unable to decrement or add
* @throws EVCacheException
* in the circumstance where timeout is exceeded or queue is
* full
*
*/
public long decr(String key, long by, long def, int exp) throws EVCacheException;
/**
* Append the given value to the existing value in EVCache. You cannot
* append if the key does not exist in EVCache. If the value has not changed
* then false will be returned.
*
* @param key
* the key under which this object should be appended. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param T
* the value to be appended
* @param tc
* the transcoder the will be used for serialization
* @param timeToLive
* the expiration of this object i.e. less than 30 days in
* seconds or the exact expiry time as UNIX time
*
* @return Array of futures representing the processing of this operation
* across all the replicas
* @throws EVCacheException
* in the circumstance where queue is too full to accept any
* more requests or issues Serializing the value or any IO
* Related issues
*/
<T> Future<Boolean>[] append(String key, T value, Transcoder<T> tc, int timeToLive) throws EVCacheException;
/**
* Append the given value to the existing value in EVCache. You cannot
* append if the key does not exist in EVCache. If the value has not changed
* or does not exist then false will be returned.
*
* @param key
* the key under which this object should be appended. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param T
* the value to be appended
* @param timeToLive
* the expiration of this object i.e. less than 30 days in
* seconds or the exact expiry time as UNIX time
*
* @return Array of futures representing the processing of this operation
* across all the replicas
* @throws EVCacheException
* in the circumstance where queue is too full to accept any
* more requests or issues Serializing the value or any IO
* Related issues
*/
<T> Future<Boolean>[] append(String key, T value, int timeToLive) throws EVCacheException;
/**
* @deprecated Please use {@link #<T> EVCacheLatch add(String, T, Transcoder<T> , int, Policy) throws EVCacheException;}
*
* Add the given value to EVCache. You cannot add if the key already exist in EVCache.
*
* @param key
* the key which this object should be added to. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param T
* the value to be added
* @param tc
* the transcoder the will be used for serialization
* @param timeToLive
* the expiration of this object i.e. less than 30 days in
* seconds or the exact expiry time as UNIX time
*
* @return boolean which indicates if the add was successful or not.
* The operation will fail with a false response if the data already exists in EVCache.
*
* @throws EVCacheException
* in the rare circumstance where queue is too full to accept
* any more requests or issues Serializing the value or any IO
* Related issues
*/
<T> boolean add(String key, T value, Transcoder<T> tc, int timeToLive) throws EVCacheException;
/**
* Add the given value to EVCache. You cannot add if the key already exist in EVCache.
*
* @param key
* the key which this object should be added to. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param T
* the value to be added
* @param tc
* the transcoder the will be used for serialization
* @param timeToLive
* the expiration of this object i.e. less than 30 days in
* seconds or the exact expiry time as UNIX time
* @param policy
* The Latch will be returned based on the Policy. The Latch can then be used to await until the count down has reached to 0 or the specified time has elapsed.
*
*
* @return EVCacheLatch which will encompasses the Operation. You can block
* on the Operation to ensure all adds are successful. If there are any partial success
* The client will try and fix the Data.
*
*
* @throws EVCacheException
* in the rare circumstance where queue is too full to accept
* any more requests or issues Serializing the value or any IO
* Related issues
*/
<T> EVCacheLatch add(String key, T value, Transcoder<T> tc, int timeToLive, Policy policy) throws EVCacheException;
/**
* Touch the given key and reset its expiration time.
*
* @param key
* the key to touch. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param ttl
* the new expiration time in seconds
*
* @return Array of futures representing the processing of this operation
* across all the replicas
* @throws EVCacheException
* in the rare circumstance where queue is too full to accept
* any more requests or issues Serializing the value or any IO
* Related issues
*/
<T> Future<Boolean>[] touch(String key, int ttl) throws EVCacheException;
/**
* Touch the given key and reset its expiration time.
*
* @param key
* the key to touch. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param ttl
* the new expiration time in seconds
*
* @param policy
* The Latch will be returned based on the Policy. The Latch can
* then be used to await until the count down has reached to 0 or
* the specified time has elapsed.
*
* @return EVCacheLatch which will encompasses the Operation. You can block
* on the Operation based on the policy to ensure the required
* criteria is met. The Latch can also be queried to get details on
* status of the operations
*
* @throws EVCacheException
* in the rare circumstance where queue is too full to accept
* any more requests or any IO Related issues
*/
<T> EVCacheLatch touch(String key, int ttl, EVCacheLatch.Policy policy) throws EVCacheException;
/**
* Append the given value to the existing value in EVCache. If the Key does not exist the the key will added.
*
*
* @param key
* the key under which this object should be appended or Added. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param T
* the value to be appended
* @param tc
* the transcoder the will be used for serialization
* @param timeToLive
* the expiration of this object i.e. less than 30 days in
* seconds or the exact expiry time as UNIX time
*
* @return Array of futures representing the processing of this operation
* across all the replicas
* @throws EVCacheException
* in the circumstance where queue is too full to accept any
* more requests or issues Serializing the value or any IO
* Related issues
*/
<T> Future<Boolean>[] appendOrAdd(String key, T value, Transcoder<T> tc, int timeToLive) throws EVCacheException;
/**
* Append the given value to the existing value in EVCache. If the Key does not exist the the key will added.
*
*
* @param key
* the key under which this object should be appended or Added. Ensure the
* key is properly encoded and does not contain whitespace or
* control characters. The max length of the key (including prefix)
* is 200 characters.
* @param T
* the value to be appended
* @param tc
* the transcoder the will be used for serialization
* @param timeToLive
* the expiration of this object i.e. less than 30 days in
* seconds or the exact expiry time as UNIX time
*
* @param policy
* The Latch will be returned based on the Policy. The Latch can then be used to await until the count down has reached to 0 or the specified time has elapsed.
*
* @return EVCacheLatch which will encompasses the Operation. You can block
* on the Operation based on the policy to ensure the required
* criteria is met. The Latch can also be queried to get details on
* status of the operations
*
* @throws EVCacheException
* in the circumstance where queue is too full to accept any
* more requests or issues Serializing the value or any IO
* Related issues
*/
<T> EVCacheLatch appendOrAdd(String key, T value, Transcoder<T> tc, int timeToLive, Policy policy) throws EVCacheException;
/**
* The {@code appName} that will be used by this {@code EVCache}.
*
* @param The
* name of the EVCache App cluster.
* @return this {@code Builder} object
*/
String getAppName();
/**
* The {@code cachePrefix} that will be used by this {@code EVCache}.
*
* @param The
* name of the EVCache App cluster.
* @return this {@code Builder} object
*/
String getCachePrefix();
/**
* A Builder that builds an EVCache based on the specified App Name, cache
* Name, TTl and Transcoder.
*
* @author smadappa
*/
public class Builder {
private static final Logger logger = LoggerFactory.getLogger(EVCacheImpl.class);
private String _appName;
private String _cachePrefix = null;
private int _ttl = 900;
private Transcoder<?> _transcoder = null;
private boolean _serverGroupRetry = true;
private boolean _enableExceptionThrowing = false;
private List<Customizer> _customizers = new ArrayList<>();
@Inject
private EVCacheClientPoolManager _poolManager;
/**
* Customizers allow post-processing of the Builder. This affords a way for libraries to
* perform customization.
*/
@FunctionalInterface
public interface Customizer {
void customize(final String cacheName, final Builder builder);
}
public static class Factory {
public Builder createInstance(String appName) {
return Builder.forApp(appName);
}
}
public static Builder forApp(final String appName) {
return new Builder().setAppName(appName);
}
public Builder() {
}
public Builder withConfigurationProperties(
final EVCacheClientPoolConfigurationProperties configurationProperties) {
return this
.setCachePrefix(configurationProperties.getKeyPrefix())
.setDefaultTTL(configurationProperties.getTimeToLive())
.setRetry(configurationProperties.getRetryEnabled())
.setExceptionThrowing(configurationProperties.getExceptionThrowingEnabled());
}
/**
* The {@code appName} that will be used by this {@code EVCache}.
*
* @param The
* name of the EVCache App cluster.
* @return this {@code Builder} object
*/
public Builder setAppName(String appName) {
if (appName == null) throw new IllegalArgumentException("param appName cannot be null.");
this._appName = appName.toUpperCase(Locale.US);
if (!_appName.startsWith("EVCACHE")) logger.warn("Make sure the app you are connecting to is EVCache App");
return this;
}
/**
* Adds {@code cachePrefix} to the key. This ensures there are no cache
* collisions if the same EVCache app is used across multiple use cases.
* If the cache is not shared we recommend to set this to
* <code>null</code>. Default is <code>null</code>.
*
* @param cacheName.
* The cache prefix cannot contain colon (':') in it.
* @return this {@code Builder} object
*/
public Builder setCachePrefix(String cachePrefix) {
if (_cachePrefix != null && _cachePrefix.indexOf(':') != -1) throw new IllegalArgumentException(
"param cacheName cannot contain ':' character.");
this._cachePrefix = cachePrefix;
return this;
}
/**
* @deprecated Please use {@link #setCachePrefix(String)}
* @see #setCachePrefix(String)
*
* Adds {@code cacheName} to the key. This ensures there are no
* cache collisions if the same EVCache app is used for across
* multiple use cases.
*
* @param cacheName
* @return this {@code Builder} object
*/
public Builder setCacheName(String cacheName) {
return setCachePrefix(cacheName);
}
/**
* The default Time To Live (TTL) for items in {@link EVCache} in
* seconds. You can override the value by passing the desired TTL with
* {@link EVCache#set(String, Object, int)} operations.
*
* @param ttl. Default is 900 seconds.
* @return this {@code Builder} object
*/
public Builder setDefaultTTL(int ttl) {
if (ttl < 0) throw new IllegalArgumentException("Time to Live cannot be less than 0.");
this._ttl = ttl;
return this;
}
/**
* The default Time To Live (TTL) for items in {@link EVCache} in
* seconds. You can override the value by passing the desired TTL with
* {@link EVCache#set(String, Object, int)} operations.
*
* @param ttl. Default is 900 seconds.
* @return this {@code Builder} object
*/
public Builder setDefaultTTL(@Nullable final Duration ttl) {
if (ttl == null) {
return this;
}
return setDefaultTTL((int) ttl.getSeconds());
}
@VisibleForTesting
Transcoder<?> getTranscoder() {
return this._transcoder;
}
/**
* The default {@link Transcoder} to be used for serializing and
* de-serializing items in {@link EVCache}.
*
* @param transcoder
* @return this {@code Builder} object
*/
public <T> Builder setTranscoder(Transcoder<T> transcoder) {
this._transcoder = transcoder;
return this;
}
/**
* @deprecated Please use {@link #enableRetry()}
*
* Will enable retries across Zone (Server Group).
*
* @return this {@code Builder} object
*/
public <T> Builder enableZoneFallback() {
this._serverGroupRetry = true;
return this;
}
/**
* Will enable or disable retry across Server Group for cache misses and exceptions
* if there are multiple Server Groups for the given EVCache App and
* data is replicated across them. This ensures the Hit Rate continues
* to be unaffected whenever a server group loses instances.
*
* By Default retry is enabled.
*
* @param enableRetry whether retries are to be enabled
* @return this {@code Builder} object
*/
public Builder setRetry(boolean enableRetry) {
this._serverGroupRetry = enableRetry;
return this;
}
/**
* Will enable retry across Server Group for cache misses and exceptions
* if there are multiple Server Groups for the given EVCache App and
* data is replicated across them. This ensures the Hit Rate continues
* to be unaffected whenever a server group loses instances.
*
* By Default retry is enabled.
*
* @return this {@code Builder} object
*/
public <T> Builder enableRetry() {
this._serverGroupRetry = true;
return this;
}
/**
* Will disable retry across Server Groups. This means if the data is
* not found in one server group null is returned.
*
* @return this {@code Builder} object
*/
public <T> Builder disableRetry() {
this._serverGroupRetry = false;
return this;
}
/**
* @deprecated Please use {@link #disableRetry()}
*
* Will disable retry across Zone (Server Group).
*
* @return this {@code Builder} object
*/
public <T> Builder disableZoneFallback() {
this._serverGroupRetry = false;
return this;
}
/**
* By Default exceptions are not propagated and null values are
* returned. By enabling exception propagation we return the
* {@link EVCacheException} whenever the operations experience them.
*
* @param enableExceptionThrowing whether exception throwing is to be enabled
* @return this {@code Builder} object
*/
public Builder setExceptionThrowing(boolean enableExceptionThrowing) {
this._enableExceptionThrowing = enableExceptionThrowing;
return this;
}
/**
* By Default exceptions are not propagated and null values are
* returned. By enabling exception propagation we return the
* {@link EVCacheException} whenever the operations experience them.
*
* @return this {@code Builder} object
*/
public <T> Builder enableExceptionPropagation() {
this._enableExceptionThrowing = true;
return this;
}
/**
* Adds customizers to be applied by {@code customize}.
*
* @param customizers List of {@code Customizer}s
* @return this {@code Builder} object
*/
public Builder addCustomizers(@Nullable final List<Customizer> customizers) {
this._customizers.addAll(customizers);
return this;
}
/**
* Applies {@code Customizer}s added through {@code addCustomizers} to {@this}.
*
* @return this {@code Builder} object
*/
public Builder customize() {
_customizers.forEach(customizer -> {
customizeWith(customizer);
});
return this;
}
/**
* Customizes {@this} with the {@code customizer}.
*
* @param customizer {@code Customizer} or {@code Consumer<String, Builder>} to be applied to {@code this}.
* @return this {@code Builder} object
*/
public Builder customizeWith(final Customizer customizer) {
customizer.customize(this._appName, this);
return this;
}
/**
* The EVCache pool manager that will be used by this {@code EVCache}.
* @param poolManager
* @return this {@code Builder} object
*/
public Builder setPoolManager(EVCacheClientPoolManager poolManager) {
_poolManager = poolManager;
return this;
}
protected EVCache newImpl(String appName, String cachePrefix, int ttl, Transcoder<?> transcoder, boolean serverGroupRetry, boolean enableExceptionThrowing, EVCacheClientPoolManager poolManager) {
return new EVCacheImpl(appName, cachePrefix, ttl, transcoder, serverGroupRetry, enableExceptionThrowing, poolManager);
}
/**
* Returns a newly created {@code EVCache} based on the contents of the
* {@code Builder}.
*/
@SuppressWarnings("deprecation")
public EVCache build() {
if (_poolManager == null) {
_poolManager = EVCacheClientPoolManager.getInstance();
if (logger.isDebugEnabled()) logger.debug("_poolManager - " + _poolManager + " through getInstance");
}
if (_appName == null) {
throw new IllegalArgumentException("param appName cannot be null.");
}
if(_cachePrefix != null) {
for(int i = 0; i < _cachePrefix.length(); i++) {
if(Character.isWhitespace(_cachePrefix.charAt(i))){
throw new IllegalArgumentException("Cache Prefix ``" + _cachePrefix + "`` contains invalid character at position " + i );
}
}
}
customize();
return newImpl(_appName, _cachePrefix, _ttl, _transcoder, _serverGroupRetry, _enableExceptionThrowing, _poolManager);
}
}