Skip to content

Commit

Permalink
Java: Add persist() command (valkey-io#1157)
Browse files Browse the repository at this point in the history
* Add persist() command to java (#148)

Signed-off-by: Andrew Carbonetto <andrew.carbonetto@improving.com>

---------

Signed-off-by: Andrew Carbonetto <andrew.carbonetto@improving.com>
  • Loading branch information
acarbonetto authored and cyip10 committed Jun 24, 2024
1 parent 55b5a0d commit 0e3de79
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 0 deletions.
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 @@ -35,6 +35,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.PTTL;
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 @@ -600,6 +601,12 @@ public CompletableFuture<Long> pttl(@NonNull String key) {
return commandManager.submitNewCommand(PTTL, new String[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<Boolean> persist(@NonNull String key) {
return commandManager.submitNewCommand(
Persist, new String[] {key}, this::handleBooleanResponse);
}

@Override
public CompletableFuture<String> type(@NonNull String key) {
return commandManager.submitNewCommand(Type, new String[] {key}, this::handleStringResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,23 @@ CompletableFuture<Boolean> pexpireAt(
*/
CompletableFuture<Long> pttl(String key);

/**
* Removes 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);

/**
* Returns the string representation of the type of the value stored at <code>key</code>.
*
Expand Down
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 @@ -42,6 +42,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.PTTL;
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 @@ -1289,6 +1290,22 @@ public T pttl(@NonNull String key) {
return getThis();
}

/**
* Removes 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();
}

/**
* Returns the server time.
*
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 @@ -53,6 +53,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.PTTL;
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 @@ -600,6 +601,28 @@ public void pttl_returns_success() {
assertEquals(pttl, response.get());
}

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

CompletableFuture<Boolean> testResponse = new CompletableFuture<>();
testResponse.complete(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 @@ -40,6 +40,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.PExpire;
import static redis_request.RedisRequestOuterClass.RequestType.PExpireAt;
import static redis_request.RedisRequestOuterClass.RequestType.PTTL;
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 @@ -389,6 +390,9 @@ public void transaction_builds_protobuf_request(BaseTransaction<?> transaction)
transaction.time();
results.add(Pair.of(Time, ArgsArray.newBuilder().build()));

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

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

Expand Down
19 changes: 19 additions & 0 deletions java/integTest/src/test/java/glide/SharedCommandTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,25 @@ public void expire_pexpire_and_pttl_with_positive_timeout(BaseClient client) {
assertTrue(pttlResult <= 10000L);
}

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

assertFalse(client.persist(key).get());

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

assertTrue(client.expire(key, 10L).get());
Long persistAmount = client.ttl(key).get();
assertTrue(0L <= persistAmount && persistAmount <= 10L);
assertTrue(client.persist(key).get());

assertEquals(-1L, client.ttl(key).get());
}

@SneakyThrows
@ParameterizedTest
@MethodSource("getClients")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,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 @@ -107,6 +108,7 @@ public static Object[] transactionTestResult() {
(long) value1.length(), // strlen(key2)
new String[] {value1, value2},
1L,
Boolean.FALSE, // persist(key1)
1L,
null,
1L,
Expand Down

0 comments on commit 0e3de79

Please sign in to comment.