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

Java: Add persist() command #148

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.Persist;
import static redis_request.RedisRequestOuterClass.RequestType.RPop;
import static redis_request.RedisRequestOuterClass.RequestType.RPush;
import static redis_request.RedisRequestOuterClass.RequestType.SAdd;
Expand Down Expand Up @@ -586,4 +587,10 @@ public CompletableFuture<Long> zrem(@NonNull String key, @NonNull String[] membe
public CompletableFuture<Long> zcard(@NonNull String key) {
return commandManager.submitNewCommand(Zcard, new String[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<Boolean> persist(@NonNull String key) {
return commandManager.submitNewCommand(
Persist, new String[] {key}, this::handleBooleanResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,21 @@ CompletableFuture<Boolean> pexpireAt(
* }</pre>
*/
CompletableFuture<Long> ttl(String key);

/**
* Remove the existing timeout on <code>key</code>, turning the <code>key</code> from volatile (a
* <code>key</code> with an expire set) to persistent (a <code>key</code> that will never expire
* as no timeout is associated).
*
* @see <a href="https://redis.io/commands/persist/">redis.io</a> for details.
* @param key The <code>key</code> to remove the existing timeout on.
* @return <code>false</code> if <code>key</code> does not exist or does not have an associated
* timeout, <code>true</code> if the timeout has been removed.
* @example
* <pre>{@code
* Boolean timeoutRemoved = client.persist("my_key").get();
* assert timeoutRemoved; // Indicates that the timeout associated with the key "my_key" was successfully removed.
* }</pre>
*/
CompletableFuture<Boolean> persist(String key);
}
17 changes: 17 additions & 0 deletions java/client/src/main/java/glide/api/models/BaseTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.Persist;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
import static redis_request.RedisRequestOuterClass.RequestType.RPop;
import static redis_request.RedisRequestOuterClass.RequestType.RPush;
Expand Down Expand Up @@ -1241,6 +1242,22 @@ public T zcard(@NonNull String key) {
return getThis();
}

/**
* Remove the existing timeout on <code>key</code>, turning the <code>key</code> from volatile (a
* <code>key</code> with an expire set) to persistent (a <code>key</code> that will never expire
* as no timeout is associated).
*
* @see <a href="https://redis.io/commands/persist/">redis.io</a> for details.
* @param key The <code>key</code> to remove the existing timeout on.
* @return Command Response - <code>false</code> if <code>key</code> does not exist or does not
* have an associated timeout, <code>true</code> if the timeout has been removed.
*/
public T persist(@NonNull String key) {
ArgsArray commandArgs = buildArgs(new String[] {key});
protobufTransaction.addCommands(buildCommand(Persist, commandArgs));
return getThis();
}

/** Build protobuf {@link Command} object for given command and arguments. */
protected Command buildCommand(RequestType requestType) {
return buildCommand(requestType, buildArgs());
Expand Down
23 changes: 23 additions & 0 deletions java/client/src/test/java/glide/api/RedisClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.Persist;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
import static redis_request.RedisRequestOuterClass.RequestType.RPop;
import static redis_request.RedisRequestOuterClass.RequestType.RPush;
Expand Down Expand Up @@ -551,6 +552,28 @@ public void ttl_returns_success() {
assertEquals(ttl, response.get());
}

@SneakyThrows
@Test
public void persist_returns_success() {
// setup
String key = "testKey";
Boolean isTimeoutRemoved = true;

CompletableFuture<Boolean> testResponse = mock(CompletableFuture.class);
when(testResponse.get()).thenReturn(isTimeoutRemoved);

// match on protobuf request
when(commandManager.<Boolean>submitNewCommand(eq(Persist), eq(new String[] {key}), any()))
.thenReturn(testResponse);

// exercise
CompletableFuture<Boolean> response = service.persist(key);

// verify
assertEquals(testResponse, response);
assertEquals(isTimeoutRemoved, response.get());
}

@SneakyThrows
@Test
public void info_returns_success() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.MSet;
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.Persist;
import static redis_request.RedisRequestOuterClass.RequestType.Ping;
import static redis_request.RedisRequestOuterClass.RequestType.RPop;
import static redis_request.RedisRequestOuterClass.RequestType.RPush;
Expand Down Expand Up @@ -372,6 +373,9 @@ public void transaction_builds_protobuf_request(BaseTransaction<?> transaction)
transaction.zcard("key");
results.add(Pair.of(Zcard, ArgsArray.newBuilder().addArgs("key").build()));

transaction.persist("key");
results.add(Pair.of(Persist, ArgsArray.newBuilder().addArgs("key").build()));

var protobufTransaction = transaction.getProtobufTransaction().build();

for (int idx = 0; idx < protobufTransaction.getCommandsCount(); idx++) {
Expand Down
13 changes: 13 additions & 0 deletions java/integTest/src/test/java/glide/SharedCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,19 @@ public void expireAt_pexpireAt_and_ttl_with_non_existing_key(BaseClient client)
assertEquals(-2L, client.ttl(key).get());
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
public void persist_on_existing_key(BaseClient client) {
String key = UUID.randomUUID().toString();

assertEquals(OK, client.set(key, "foo").get());
assertFalse(client.persist(key).get());

assertTrue(client.expire(key, 10).get());
assertTrue(client.persist(key).get());
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static BaseTransaction<?> transactionTest(BaseTransaction<?> baseTransact
baseTransaction.customCommand(new String[] {"MGET", key1, key2});

baseTransaction.exists(new String[] {key1});
baseTransaction.persist(key1);

baseTransaction.del(new String[] {key1});
baseTransaction.get(key1);
Expand Down Expand Up @@ -101,6 +102,7 @@ public static Object[] transactionTestResult() {
null,
new String[] {value1, value2},
1L,
Boolean.FALSE,
1L,
null,
1L,
Expand Down
Loading