Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail-fast if max-idle-seconds is set below 2 seconds #14727

Merged
merged 8 commits into from Mar 27, 2019
Expand Up @@ -126,6 +126,7 @@
import com.hazelcast.map.impl.querycache.subscriber.QueryCacheEndToEndProvider;
import com.hazelcast.map.impl.querycache.subscriber.QueryCacheRequest;
import com.hazelcast.map.impl.querycache.subscriber.SubscriberContext;
import com.hazelcast.map.impl.recordstore.RecordStore;
import com.hazelcast.map.journal.EventJournalMapEvent;
import com.hazelcast.map.listener.MapListener;
import com.hazelcast.map.listener.MapPartitionLostListener;
Expand Down Expand Up @@ -175,6 +176,7 @@
import static com.hazelcast.util.CollectionUtil.objectToDataCollection;
import static com.hazelcast.util.ExceptionUtil.rethrow;
import static com.hazelcast.util.MapUtil.createHashMap;
import static com.hazelcast.util.Preconditions.checkMinTimeIfPositive;
import static com.hazelcast.util.Preconditions.checkNotInstanceOf;
import static com.hazelcast.util.Preconditions.checkNotNull;
import static com.hazelcast.util.SortingUtil.getSortedQueryResultSet;
Expand Down Expand Up @@ -202,6 +204,9 @@ public class ClientMapProxy<K, V> extends ClientProxy
protected static final String NULL_AGGREGATOR_IS_NOT_ALLOWED = "Aggregator should not be null!";
protected static final String NULL_PROJECTION_IS_NOT_ALLOWED = "Projection should not be null!";

protected static final String MAX_IDLE_TIME_IS_TOO_SMALL = "Parameter maxIdle in seconds representation must be greater or"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not arguing my english is perfect here but I think the message must be "greater than or equal to"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Fixed. Thanks.

+ " equal than " + RecordStore.MIN_ALLOWED_MAX_IDLE;

@SuppressWarnings("unchecked")
protected static final ClientMessageDecoder GET_ASYNC_RESPONSE_DECODER = new ClientMessageDecoder() {
@Override
Expand Down Expand Up @@ -338,6 +343,8 @@ public V put(K key, V value) {
public V put(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) {
checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, RecordStore.MIN_ALLOWED_MAX_IDLE, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

return putInternal(ttl, ttlUnit, maxIdle, maxIdleUnit, key, value);
}
Expand Down Expand Up @@ -447,6 +454,8 @@ public ICompletableFuture<V> putAsync(K key, V value, long ttl, TimeUnit timeuni
public ICompletableFuture<V> putAsync(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) {
checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, RecordStore.MIN_ALLOWED_MAX_IDLE, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

return putAsyncInternal(ttl, ttlUnit, maxIdle, maxIdleUnit, key, value);
}
Expand Down Expand Up @@ -488,6 +497,8 @@ public ICompletableFuture<Void> setAsync(K key, V value, long ttl, TimeUnit time
public ICompletableFuture<Void> setAsync(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) {
checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, RecordStore.MIN_ALLOWED_MAX_IDLE, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

return setAsyncInternal(ttl, ttlUnit, maxIdle, maxIdleUnit, key, value);
}
Expand Down Expand Up @@ -598,6 +609,8 @@ public void putTransient(K key, V value, long ttl, TimeUnit timeunit) {
public void putTransient(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) {
checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, RecordStore.MIN_ALLOWED_MAX_IDLE, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

putTransientInternal(ttl, ttlUnit, maxIdle, maxIdleUnit, key, value);
}
Expand Down Expand Up @@ -638,6 +651,8 @@ public V putIfAbsent(K key, V value, long ttl, TimeUnit timeunit) {
public V putIfAbsent(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) {
checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, RecordStore.MIN_ALLOWED_MAX_IDLE, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

return putIfAbsentInternal(ttl, ttlUnit, maxIdle, maxIdleUnit, key, value);
}
Expand Down Expand Up @@ -708,6 +723,8 @@ public void set(K key, V value, long ttl, TimeUnit timeunit) {
public void set(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit) {
checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, RecordStore.MIN_ALLOWED_MAX_IDLE, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

setInternal(ttl, ttlUnit, maxIdle, maxIdleUnit, key, value);
}
Expand Down
Expand Up @@ -27,6 +27,7 @@
import com.hazelcast.map.EntryProcessor;
import com.hazelcast.map.QueryResultSizeExceededException;
import com.hazelcast.map.impl.MapListenerAdapter;
import com.hazelcast.map.impl.recordstore.RecordStore;
import com.hazelcast.map.listener.MapListener;
import com.hazelcast.query.Predicate;
import com.hazelcast.query.TruePredicate;
Expand All @@ -48,6 +49,7 @@

import static java.util.Collections.emptyMap;
import static java.util.Collections.emptySet;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.assertEquals;

@RunWith(HazelcastParallelClassRunner.class)
Expand Down Expand Up @@ -613,6 +615,42 @@ public void testIssue7631_emptyKeysSupported() {
assertEquals(emptyMap(), res);
}

@Test(expected = IllegalArgumentException.class)
public void testPutAsyncWithNotAllowedMaxIdleTime() {
map.putAsync("key1", "value1", 1, TimeUnit.MINUTES,
RecordStore.MIN_ALLOWED_MAX_IDLE - 1, SECONDS);
}

@Test(expected = IllegalArgumentException.class)
public void testSetAsyncWithNotAllowedMaxIdleTime() {
map.setAsync("key1", "value1", 1, TimeUnit.MINUTES,
RecordStore.MIN_ALLOWED_MAX_IDLE - 1, SECONDS);
}

@Test(expected = IllegalArgumentException.class)
public void testPutWithNotAllowedMaxIdleTime() {
map.put("key1", "value1", 1, TimeUnit.MINUTES,
RecordStore.MIN_ALLOWED_MAX_IDLE - 1, SECONDS);
}

@Test(expected = IllegalArgumentException.class)
public void testPutTransientWithNotAllowedMaxIdleTime() {
map.putTransient("key1", "value1", 1, TimeUnit.MINUTES,
RecordStore.MIN_ALLOWED_MAX_IDLE - 1, SECONDS);
}

@Test(expected = IllegalArgumentException.class)
public void testPutIfAbsentWithNotAllowedMaxIdleTime() {
map.putIfAbsent("key1", "value1", 1, TimeUnit.MINUTES,
RecordStore.MIN_ALLOWED_MAX_IDLE - 1, SECONDS);
}

@Test(expected = IllegalArgumentException.class)
public void testSetWithNotAllowedMaxIdleTime() {
map.set("key1", "value1", 1, TimeUnit.MINUTES,
RecordStore.MIN_ALLOWED_MAX_IDLE - 1, SECONDS);
}

private static class NoOpEntryProcessor implements EntryProcessor {
@Override
public Object process(Map.Entry entry) {
Expand Down
17 changes: 16 additions & 1 deletion hazelcast/src/main/java/com/hazelcast/config/MapConfig.java
Expand Up @@ -87,6 +87,11 @@ public class MapConfig implements SplitBrainMergeTypeProvider, IdentifiedDataSer
*/
public static final int DEFAULT_MAX_IDLE_SECONDS = 0;

/**
* The number of minimum and non-zero time to wait eviction in seconds.
*/
public static final int MIN_ALLOWED_MAX_IDLE_SECONDS = 2;

/**
* Default policy for eviction.
*/
Expand Down Expand Up @@ -434,12 +439,22 @@ public int getMaxIdleSeconds() {
* Maximum number of seconds for each entry to stay idle in the map. Entries that are
* idle (not touched) for more than {@code maxIdleSeconds} will get automatically evicted from the map.
* Entry is touched if {@code get()}, {@code getAll()}, {@code put()} or {@code containsKey()} is called.
* Any integer between {@code 0} and {@code Integer.MAX_VALUE}.
* {@code 0} and any integer between {@value #MIN_ALLOWED_MAX_IDLE_SECONDS} and {@code Integer.MAX_VALUE} (inclusive)
* are allowed.
* {@code 0} means infinite. Default is {@code 0}.
*
* @param maxIdleSeconds the maxIdleSeconds (the maximum number of seconds for each entry to stay idle in the map) to set
* @throws IllegalArgumentException if maxIdleSeconds is negative or non-zero and less
* than {@value #MIN_ALLOWED_MAX_IDLE_SECONDS}.
*/
public MapConfig setMaxIdleSeconds(int maxIdleSeconds) {
if (maxIdleSeconds < 0) {
throw new IllegalArgumentException("Parameter maxIdleSeconds can not get a negative value");
}
if (maxIdleSeconds != DEFAULT_MAX_IDLE_SECONDS && maxIdleSeconds < MIN_ALLOWED_MAX_IDLE_SECONDS) {
throw new IllegalArgumentException("Parameter maxIdleSeconds must be greater or equal than "
+ MIN_ALLOWED_MAX_IDLE_SECONDS);
}
this.maxIdleSeconds = maxIdleSeconds;
return this;
}
Expand Down
30 changes: 24 additions & 6 deletions hazelcast/src/main/java/com/hazelcast/core/IMap.java
Expand Up @@ -776,7 +776,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* <p>
* The entry will expire and get evicted after the Max Idle time. If the MaxIdle is 0,
* then the entry lives forever. If the MaxIdle is negative, then the MaxIdle
* from the map configuration will be used (default: forever).
* from the map configuration will be used (default: forever). If the MaxIdle is positive, it must not be less than
* {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent.
* <pre>
* ICompletableFuture future = map.putAsync(key, value, ttl, timeunit);
* // do some other stuff, when ready get the result
Expand Down Expand Up @@ -852,6 +853,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* @param maxIdleUnit time unit for the Max-Idle
* @return ICompletableFuture from which the old value of the key can be retrieved
* @throws NullPointerException if the specified key, value, ttlUnit or maxIdleUnit are null
* @throws IllegalArgumentException if maxIdle is greater than zero and less
* than {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent
* @see ICompletableFuture
* @see #setAsync(Object, Object, long, TimeUnit)
*/
Expand Down Expand Up @@ -1007,7 +1010,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* <p>
* The entry will expire and get evicted after the TTL. If the TTL is 0,
* then the entry lives forever. If the TTL is negative, then the TTL
* from the map configuration will be used (default: forever).
* from the map configuration will be used (default: forever). If the MaxIdle is positive, it must not be less than
* * {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent.
* <p>
* The entry will expire and get evicted after the Max Idle time. If the MaxIdle is 0,
* then the entry lives forever. If the MaxIdle is negative, then the MaxIdle
Expand Down Expand Up @@ -1078,6 +1082,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* @return ICompletableFuture on which client code can block waiting for the operation to complete
* or provide an {@link ExecutionCallback} to be invoked upon set operation completion
* @throws NullPointerException if the specified key, value, ttlUnit or maxIdleUnit are null
* @throws IllegalArgumentException if maxIdle is greater than zero and less
* than {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent
* @see ICompletableFuture
*/
ICompletableFuture<Void> setAsync(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit);
Expand Down Expand Up @@ -1248,7 +1254,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* <p>
* The entry will expire and get evicted after the Max Idle time. If the MaxIdle is 0,
* then the entry lives forever. If the MaxIdle is negative, then the MaxIdle
* from the map configuration will be used (default: forever).
* from the map configuration will be used (default: forever). If the MaxIdle is positive, it must not be less than
* * {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent.
* <p>
* <b>Warning 1:</b>
* <p>
Expand Down Expand Up @@ -1295,6 +1302,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* @param maxIdleUnit time unit for the Max-Idle
* @return old value of the entry
* @throws NullPointerException if the specified key, value, ttlUnit or maxIdleUnit are null
* @throws IllegalArgumentException if maxIdle is greater than zero and less
* than {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent
*/
V put(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit);

Expand Down Expand Up @@ -1336,7 +1345,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* <p>
* The entry will expire and get evicted after the Max Idle time. If the MaxIdle is 0,
* then the entry lives forever. If the MaxIdle is negative, then the MaxIdle
* from the map configuration will be used (default: forever).
* from the map configuration will be used (default: forever). If the MaxIdle is positive, it must not be less than
* * {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent.
* <p>
* <b>Warning 1:</b>
* <p>
Expand All @@ -1356,6 +1366,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* (0 means infinite, negative means map config default)
* @param maxIdleUnit time unit for the Max-Idle
* @throws NullPointerException if the specified key, value, ttlUnit or maxIdleUnit are null
* @throws IllegalArgumentException if maxIdle is greater than zero and less
* than {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent
*/
void putTransient(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit);

Expand Down Expand Up @@ -1454,7 +1466,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* <p>
* The entry will expire and get evicted after the Max Idle time. If the MaxIdle is 0,
* then the entry lives forever. If the MaxIdle is negative, then the MaxIdle
* from the map configuration will be used (default: forever).
* from the map configuration will be used (default: forever). If the MaxIdle is positive, it must not be less than
* * {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent.
* <p>
* <b>Warning 1:</b>
* <p>
Expand Down Expand Up @@ -1498,6 +1511,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* @param maxIdleUnit time unit for the Max-Idle
* @return old value of the entry
* @throws NullPointerException if the specified key, value, ttlUnit or maxIdleUnit are null
* @throws IllegalArgumentException if maxIdle is greater than zero and less
* than {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent
*/
V putIfAbsent(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit);
/**
Expand Down Expand Up @@ -1650,7 +1665,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* <p>
* The entry will expire and get evicted after the Max Idle time. If the MaxIdle is 0,
* then the entry lives forever. If the MaxIdle is negative, then the MaxIdle
* from the map configuration will be used (default: forever).
* from the map configuration will be used (default: forever). If the MaxIdle is positive, it must not be less than
* * {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent.
* <p>
* <b>Warning 1:</b>
* <p>
Expand Down Expand Up @@ -1683,6 +1699,8 @@ public interface IMap<K, V> extends ConcurrentMap<K, V>, LegacyAsyncMap<K, V> {
* (0 means infinite, negative means map config default)
* @param maxIdleUnit time unit for the Max-Idle
* @throws NullPointerException if the specified key, value, ttlUnit or maxIdleUnit are null
* @throws IllegalArgumentException if maxIdle is greater than zero and less
* than {@value com.hazelcast.config.MapConfig#MIN_ALLOWED_MAX_IDLE_SECONDS} in seconds equivalent
*/
void set(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit maxIdleUnit);

Expand Down
Expand Up @@ -91,6 +91,7 @@
import static com.hazelcast.map.impl.recordstore.RecordStore.DEFAULT_MAX_IDLE;
import static com.hazelcast.util.ExceptionUtil.rethrow;
import static com.hazelcast.util.MapUtil.createHashMap;
import static com.hazelcast.util.Preconditions.checkMinTimeIfPositive;
import static com.hazelcast.util.Preconditions.checkNoNullInside;
import static com.hazelcast.util.Preconditions.checkNotInstanceOf;
import static com.hazelcast.util.Preconditions.checkNotNull;
Expand Down Expand Up @@ -144,6 +145,8 @@ public V put(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUnit

checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, MapConfig.MIN_ALLOWED_MAX_IDLE_SECONDS, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

Data valueData = toData(value);
Data result = putInternal(key, valueData, ttl, ttlUnit, maxIdle, maxIdleUnit);
Expand Down Expand Up @@ -183,6 +186,8 @@ public V putIfAbsent(K key, V value, long ttl, TimeUnit timeunit, long maxIdle,

checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, MapConfig.MIN_ALLOWED_MAX_IDLE_SECONDS, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

Data valueData = toData(value);
Data result = putIfAbsentInternal(key, valueData, ttl, timeunit, maxIdle, maxIdleUnit);
Expand All @@ -207,6 +212,8 @@ public void putTransient(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdl

checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, MapConfig.MIN_ALLOWED_MAX_IDLE_SECONDS, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

Data valueData = toData(value);
putTransientInternal(key, valueData, ttl, ttlUnit, maxIdle, maxIdleUnit);
Expand Down Expand Up @@ -255,6 +262,8 @@ public void set(K key, V value, long ttl, TimeUnit ttlUnit, long maxIdle, TimeUn

checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, MapConfig.MIN_ALLOWED_MAX_IDLE_SECONDS, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

Data valueData = toData(value);
setInternal(key, valueData, ttl, ttlUnit, maxIdle, maxIdleUnit);
Expand Down Expand Up @@ -379,6 +388,8 @@ public ICompletableFuture<V> putAsync(K key, V value, long ttl, TimeUnit ttlUnit

checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, MapConfig.MIN_ALLOWED_MAX_IDLE_SECONDS, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

Data valueData = toData(value);
return new DelegatingFuture<V>(
Expand Down Expand Up @@ -411,6 +422,8 @@ public ICompletableFuture<Void> setAsync(K key, V value, long ttl, TimeUnit ttlU

checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED);
checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED);
checkMinTimeIfPositive(maxIdle, maxIdleUnit, MapConfig.MIN_ALLOWED_MAX_IDLE_SECONDS, TimeUnit.SECONDS,
MAX_IDLE_TIME_IS_TOO_SMALL);

Data valueData = toData(value);
return new DelegatingFuture<Void>(
Expand Down