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 FLUSHDB command. #1593

Merged
merged 5 commits into from
Jun 18, 2024
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
1 change: 1 addition & 0 deletions glide-core/src/protobuf/redis_request.proto
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ enum RequestType {
FunctionKill = 161;
FunctionStats = 162;
FCallReadOnly = 163;
FlushDB = 164;
LSet = 165;
XDel = 166;
XRange = 167;
Expand Down
3 changes: 3 additions & 0 deletions glide-core/src/request_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ pub enum RequestType {
FunctionKill = 161,
FunctionStats = 162,
FCallReadOnly = 163,
FlushDB = 164,
LSet = 165,
XDel = 166,
XRange = 167,
Expand Down Expand Up @@ -365,6 +366,7 @@ impl From<::protobuf::EnumOrUnknown<ProtobufRequestType>> for RequestType {
ProtobufRequestType::FunctionKill => RequestType::FunctionKill,
ProtobufRequestType::FunctionStats => RequestType::FunctionStats,
ProtobufRequestType::FCallReadOnly => RequestType::FCallReadOnly,
ProtobufRequestType::FlushDB => RequestType::FlushDB,
ProtobufRequestType::LSet => RequestType::LSet,
ProtobufRequestType::XDel => RequestType::XDel,
ProtobufRequestType::XRange => RequestType::XRange,
Expand Down Expand Up @@ -554,6 +556,7 @@ impl RequestType {
RequestType::FunctionKill => Some(get_two_word_command("FUNCTION", "KILL")),
RequestType::FunctionStats => Some(get_two_word_command("FUNCTION", "STATS")),
RequestType::FCallReadOnly => Some(cmd("FCALL_RO")),
RequestType::FlushDB => Some(cmd("FLUSHDB")),
RequestType::LSet => Some(cmd("LSET")),
RequestType::XDel => Some(cmd("XDEL")),
RequestType::XRange => Some(cmd("XRANGE")),
Expand Down
12 changes: 12 additions & 0 deletions java/client/src/main/java/glide/api/RedisClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.DBSize;
import static redis_request.RedisRequestOuterClass.RequestType.Echo;
import static redis_request.RedisRequestOuterClass.RequestType.FlushAll;
import static redis_request.RedisRequestOuterClass.RequestType.FlushDB;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionDelete;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionFlush;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionKill;
Expand Down Expand Up @@ -172,6 +173,17 @@ public CompletableFuture<String> flushall(@NonNull FlushMode mode) {
FlushAll, new String[] {mode.toString()}, this::handleStringResponse);
}

@Override
public CompletableFuture<String> flushdb() {
return commandManager.submitNewCommand(FlushDB, new String[0], this::handleStringResponse);
}

@Override
public CompletableFuture<String> flushdb(@NonNull FlushMode mode) {
return commandManager.submitNewCommand(
FlushDB, new String[] {mode.toString()}, this::handleStringResponse);
}

@Override
public CompletableFuture<String> lolwut() {
return commandManager.submitNewCommand(Lolwut, new String[0], this::handleStringResponse);
Expand Down
25 changes: 25 additions & 0 deletions java/client/src/main/java/glide/api/RedisClusterClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.FCall;
import static redis_request.RedisRequestOuterClass.RequestType.FCallReadOnly;
import static redis_request.RedisRequestOuterClass.RequestType.FlushAll;
import static redis_request.RedisRequestOuterClass.RequestType.FlushDB;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionDelete;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionFlush;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionKill;
Expand Down Expand Up @@ -343,6 +344,30 @@ public CompletableFuture<String> flushall(
FlushAll, new String[] {mode.toString()}, route, this::handleStringResponse);
}

@Override
public CompletableFuture<String> flushdb() {
return commandManager.submitNewCommand(FlushDB, new String[0], this::handleStringResponse);
}

@Override
public CompletableFuture<String> flushdb(@NonNull FlushMode mode) {
return commandManager.submitNewCommand(
FlushDB, new String[] {mode.toString()}, this::handleStringResponse);
}

@Override
public CompletableFuture<String> flushdb(@NonNull SingleNodeRoute route) {
return commandManager.submitNewCommand(
FlushDB, new String[0], route, this::handleStringResponse);
}

@Override
public CompletableFuture<String> flushdb(
@NonNull FlushMode mode, @NonNull SingleNodeRoute route) {
return commandManager.submitNewCommand(
FlushDB, new String[] {mode.toString()}, route, this::handleStringResponse);
}

@Override
public CompletableFuture<String> lolwut() {
return commandManager.submitNewCommand(Lolwut, new String[0], this::handleStringResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ public interface ServerManagementClusterCommands {
*
* @see <a href="https://valkey.io/commands/flushall/">valkey.io</a> for details.
* @param route Specifies the routing configuration for the command. The client will route the
* command to the nodes defined by <code>route</code>.
* command to the node defined by <code>route</code>.
* @return <code>OK</code>.
* @example
* <pre>{@code
Expand All @@ -371,7 +371,7 @@ public interface ServerManagementClusterCommands {
* @param mode The flushing mode, could be either {@link FlushMode#SYNC} or {@link
* FlushMode#ASYNC}.
* @param route Specifies the routing configuration for the command. The client will route the
* command to the nodes defined by <code>route</code>.
* command to the node defined by <code>route</code>.
* @return <code>OK</code>.
* @example
* <pre>{@code
Expand All @@ -382,6 +382,70 @@ public interface ServerManagementClusterCommands {
*/
CompletableFuture<String> flushall(FlushMode mode, SingleNodeRoute route);

/**
* Deletes all the keys of the currently selected database. This command never fails.<br>
* The command will be routed to all primary nodes.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @return <code>OK</code>.
* @example
* <pre>{@code
* String response = client.flushdb().get();
* assert response.equals("OK");
* }</pre>
*/
CompletableFuture<String> flushdb();

/**
* Deletes all the keys of the currently selected database. This command never fails.<br>
* The command will be routed to all primary nodes.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @param mode The flushing mode, could be either {@link FlushMode#SYNC} or {@link
* FlushMode#ASYNC}.
* @return <code>OK</code>.
* @example
* <pre>{@code
* String response = client.flushdb(ASYNC).get();
* assert response.equals("OK");
* }</pre>
*/
CompletableFuture<String> flushdb(FlushMode mode);

/**
* Deletes all the keys of the currently selected database. This command never fails.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @param route Specifies the routing configuration for the command. The client will route the
* command to the node defined by <code>route</code>.
* @return <code>OK</code>.
* @example
* <pre>{@code
* Route route = new SlotKeyRoute("key", PRIMARY);
* String response = client.flushdb(route).get();
* assert response.equals("OK");
* }</pre>
*/
CompletableFuture<String> flushdb(SingleNodeRoute route);
Copy link
Contributor

Choose a reason for hiding this comment

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

why only single node here? especially since the default is a multinode route

Copy link
Contributor

@acarbonetto acarbonetto Jun 17, 2024

Choose a reason for hiding this comment

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

  • update to multinode or update comment

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I copied that from flushall - Route includes ALL_NODES which always fails, because replicas are RO. Even though it may fail now with RANDOM route too.
In a dark future it is nice to have better route distinuishment by their target - RO and non-RO alongside with single/multi node. In that case we can put here non-RO route to protect a user.

Copy link
Collaborator

Choose a reason for hiding this comment

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

What if the users want to send to all primaries? I guess the thinking is they should use the non-route function since it defaults to all primaries?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think yes

Copy link
Contributor

Choose a reason for hiding this comment

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

They have to be smart then. Thanks for asking Bar - I guess we can either let the user fail (giving them all options) or limit their options but maybe close some edge cases.


/**
* Deletes all the keys of the currently selected database. This command never fails.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @param mode The flushing mode, could be either {@link FlushMode#SYNC} or {@link
* FlushMode#ASYNC}.
* @param route Specifies the routing configuration for the command. The client will route the
* command to the node defined by <code>route</code>.
* @return <code>OK</code>.
* @example
* <pre>{@code
* Route route = new SlotKeyRoute("key", PRIMARY);
* String response = client.flushdb(SYNC, route).get();
* assert response.equals("OK");
* }</pre>
*/
CompletableFuture<String> flushdb(FlushMode mode, SingleNodeRoute route);

/**
* Displays a piece of generative computer art and the Redis version.<br>
* The command will be routed to a random node.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,34 @@ public interface ServerManagementCommands {
*/
CompletableFuture<String> flushall(FlushMode mode);

/**
* Deletes all the keys of the currently selected database. This command never fails.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @return <code>OK</code>.
* @example
* <pre>{@code
* String response = client.flushdb().get();
* assert response.equals("OK");
* }</pre>
*/
CompletableFuture<String> flushdb();

/**
* Deletes all the keys of the currently selected database. This command never fails.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @param mode The flushing mode, could be either {@link FlushMode#SYNC} or {@link
* FlushMode#ASYNC}.
* @return <code>OK</code>.
* @example
* <pre>{@code
* String response = client.flushdb(ASYNC).get();
* assert response.equals("OK");
* }</pre>
*/
CompletableFuture<String> flushdb(FlushMode mode);

/**
* Displays a piece of generative computer art and the Redis version.
*
Expand Down
25 changes: 25 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 @@ -53,6 +53,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.FCall;
import static redis_request.RedisRequestOuterClass.RequestType.FCallReadOnly;
import static redis_request.RedisRequestOuterClass.RequestType.FlushAll;
import static redis_request.RedisRequestOuterClass.RequestType.FlushDB;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionDelete;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionFlush;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionList;
Expand Down Expand Up @@ -3027,6 +3028,30 @@ public T flushall(FlushMode mode) {
return getThis();
}

/**
* Deletes all the keys of the currently selected database. This command never fails.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @return Command Response - <code>OK</code>.
*/
public T flushdb() {
protobufTransaction.addCommands(buildCommand(FlushDB));
return getThis();
}

/**
* Deletes all the keys of the currently selected database. This command never fails.
*
* @see <a href="https://valkey.io/commands/flushdb/">valkey.io</a> for details.
* @param mode The flushing mode, could be either {@link FlushMode#SYNC} or {@link
* FlushMode#ASYNC}.
* @return Command Response - <code>OK</code>.
*/
public T flushdb(FlushMode mode) {
protobufTransaction.addCommands(buildCommand(FlushDB, buildArgs(mode.toString())));
return getThis();
}

/**
* Displays a piece of generative computer art and the Redis version.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,24 @@
* <li><code>FLUSHALL</code> command implemented by {@link RedisClient#flushall(FlushMode)},
* {@link RedisClusterClient#flushall(FlushMode)}, and {@link
* RedisClusterClient#flushall(FlushMode, SingleNodeRoute)}.
* <li><code>FLUSHDB</code> command implemented by {@link RedisClient#flushdb(FlushMode)}, {@link
* RedisClusterClient#flushdb(FlushMode)}, and {@link RedisClusterClient#flushdb(FlushMode,
* SingleNodeRoute)}.
* <li><code>FUNCTION FLUSH</code> command implemented by {@link
* RedisClient#functionFlush(FlushMode)}, {@link RedisClusterClient#functionFlush(FlushMode)},
* and {@link RedisClusterClient#functionFlush(FlushMode, Route)}.
* </ul>
*
* @see <a href="https://valkey.io/commands/flushall/">valkey.io</a> and <a
* href="https://valkey.io/commands/function-flush/">valkey.io</a>
* @see <a href="https://valkey.io/commands/flushall/">flushall</a>, <a
* href="https://valkey.io/commands/flushdb/">flushdb</a>, and <a
* href="https://valkey.io/commands/function-flush/">function flush</a> at valkey.io
*/
public enum FlushMode {
/** Flushes synchronously. */
/**
* Flushes synchronously.
*
* @since Redis 6.2 and above.
*/
SYNC,
/** Flushes asynchronously. */
ASYNC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ public interface MultiNodeRoute extends Route {}
@RequiredArgsConstructor
@Getter
public enum SimpleSingleNodeRoute implements SingleNodeRoute {
/** Route request to a random node. */
/**
* Route request to a random node.<br>
* <b>Warning</b><br>
* Don't use it with write commands, because they could be randomly routed to a replica (RO)
* node and fail.
*/
RANDOM(2);

private final int ordinal;
Expand All @@ -40,7 +45,10 @@ public enum SimpleSingleNodeRoute implements SingleNodeRoute {
@RequiredArgsConstructor
@Getter
public enum SimpleMultiNodeRoute implements MultiNodeRoute {
/** Route request to all nodes. */
/**
* Route request to all nodes. <b>Warning</b><br>
* Don't use it with write commands, they could be routed to a replica (RO) node and fail.
*/
ALL_NODES(0),
/** Route request to all primary nodes. */
ALL_PRIMARIES(1);
Expand Down
42 changes: 42 additions & 0 deletions java/client/src/test/java/glide/api/RedisClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import static redis_request.RedisRequestOuterClass.RequestType.FCall;
import static redis_request.RedisRequestOuterClass.RequestType.FCallReadOnly;
import static redis_request.RedisRequestOuterClass.RequestType.FlushAll;
import static redis_request.RedisRequestOuterClass.RequestType.FlushDB;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionDelete;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionFlush;
import static redis_request.RedisRequestOuterClass.RequestType.FunctionKill;
Expand Down Expand Up @@ -4517,6 +4518,47 @@ public void flushall_with_mode_returns_success() {
assertEquals(OK, payload);
}

@SneakyThrows
@Test
public void flushdb_returns_success() {
// setup
CompletableFuture<String> testResponse = new CompletableFuture<>();
testResponse.complete(OK);

// match on protobuf request
when(commandManager.<String>submitNewCommand(eq(FlushDB), eq(new String[0]), any()))
.thenReturn(testResponse);

// exercise
CompletableFuture<String> response = service.flushdb();
String payload = response.get();

// verify
assertEquals(testResponse, response);
assertEquals(OK, payload);
}

@SneakyThrows
@Test
public void flushdb_with_mode_returns_success() {
// setup
CompletableFuture<String> testResponse = new CompletableFuture<>();
testResponse.complete(OK);

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

// exercise
CompletableFuture<String> response = service.flushdb(SYNC);
String payload = response.get();

// verify
assertEquals(testResponse, response);
assertEquals(OK, payload);
}

@SneakyThrows
@Test
public void lolwut_returns_success() {
Expand Down
Loading
Loading