-
Notifications
You must be signed in to change notification settings - Fork 69
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 PING command #914
Changes from 10 commits
332d782
02b56fa
99b36e0
2f7760d
57a5115
40c9bf3
c302263
f78cdb6
0b2aa76
1b62d43
2cbf558
3b968f0
e68c8dd
df5d92e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,11 @@ | |
package glide.api; | ||
|
||
import static glide.ffi.resolvers.SocketListenerResolver.getSocket; | ||
import static redis_request.RedisRequestOuterClass.RequestType.Ping; | ||
|
||
import glide.api.commands.ConnectionManagementCommands; | ||
import glide.api.models.configuration.BaseClientConfiguration; | ||
import glide.api.models.exceptions.RedisException; | ||
import glide.connectors.handlers.CallbackDispatcher; | ||
import glide.connectors.handlers.ChannelHandler; | ||
import glide.connectors.resources.Platform; | ||
|
@@ -17,12 +20,12 @@ | |
import java.util.concurrent.ExecutionException; | ||
import java.util.function.BiFunction; | ||
import lombok.AllArgsConstructor; | ||
import lombok.NonNull; | ||
import response.ResponseOuterClass.Response; | ||
|
||
/** Base Client class for Redis */ | ||
@AllArgsConstructor | ||
public abstract class BaseClient implements AutoCloseable { | ||
|
||
public abstract class BaseClient implements AutoCloseable, ConnectionManagementCommands { | ||
protected final ConnectionManager connectionManager; | ||
protected final CommandManager commandManager; | ||
|
||
|
@@ -90,14 +93,49 @@ protected static CommandManager buildCommandManager(ChannelHandler channelHandle | |
} | ||
|
||
/** | ||
* Extracts the response from the Protobuf response and either throws an exception or returns the | ||
* appropriate response as an <code>Object</code>. | ||
* Extracts the value from a Redis response message and either throws an exception or returns the | ||
* value as an object of type {@link T}. If <code>isNullable</code>, than also returns <code>null | ||
* </code>. | ||
* | ||
* @param response Redis protobuf message | ||
* @return Response <code>Object</code> | ||
* @param classType Parameter {@link T} class type | ||
* @param isNullable Accepts null values in the protobuf message | ||
* @return Response as an object of type {@link T} or <code>null</code> | ||
* @param <T> return type | ||
* @throws RedisException on a type mismatch | ||
*/ | ||
private <T> T handleRedisResponse(Class classType, boolean isNullable, Response response) { | ||
Object value = | ||
new BaseCommandResponseResolver(RedisValueResolver::valueFromPointer).apply(response); | ||
if (isNullable && (value == null)) { | ||
return null; | ||
} | ||
if (classType.isInstance(value)) { | ||
return (T) value; | ||
} | ||
String className = value == null ? "null" : value.getClass().getSimpleName(); | ||
throw new RedisException( | ||
"Unexpected return type from Redis: got " | ||
+ className | ||
+ " expected " | ||
+ classType.toGenericString()); | ||
acarbonetto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
protected Object handleObjectResponse(Response response) { | ||
Yury-Fridlyand marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// convert protobuf response into Object | ||
return new BaseCommandResponseResolver(RedisValueResolver::valueFromPointer).apply(response); | ||
return handleRedisResponse(Object.class, false, response); | ||
} | ||
|
||
protected String handleStringResponse(Response response) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not necessarily for this PR - this has a very similar structure to the handleArrayResponse. protected T handleResponse<T>(Response response) {
Object value = handleObjectResponse(response);
if (value instanceof T || value == null) {
return (T) value;
}
throw new RedisException(
"Unexpected return type from Redis: got "
+ value.getClass().getSimpleName()
+ " expected " + T.getType());
}
```
of course, `T.getType()` isn't really possible and this doesn't handle primitives well, but I believe this is possible, and will remove a lot of glue code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good idea. I've updated to include the generic function - this will reduce code duplication. |
||
return handleRedisResponse(String.class, false, response); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we should make sections/regions - for handlers, for commands for all rest There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure - but let's leave this for a future update. This will be useful when we have more than 3 commands. |
||
@Override | ||
public CompletableFuture<String> ping() { | ||
return commandManager.submitNewCommand(Ping, new String[0], this::handleStringResponse); | ||
} | ||
|
||
@Override | ||
public CompletableFuture<String> ping(@NonNull String str) { | ||
return commandManager.submitNewCommand(Ping, new String[] {str}, this::handleStringResponse); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
import glide.managers.CommandManager; | ||
import glide.managers.ConnectionManager; | ||
import java.util.concurrent.CompletableFuture; | ||
import lombok.NonNull; | ||
|
||
/** | ||
* Async (non-blocking) client for Redis in Standalone mode. Use {@link #CreateClient} to request a | ||
|
@@ -25,12 +26,13 @@ protected RedisClient(ConnectionManager connectionManager, CommandManager comman | |
* @param config Redis client Configuration | ||
* @return A Future to connect and return a RedisClient | ||
*/ | ||
public static CompletableFuture<RedisClient> CreateClient(RedisClientConfiguration config) { | ||
public static CompletableFuture<RedisClient> CreateClient( | ||
@NonNull RedisClientConfiguration config) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding for consistency across all methods. @nonnull will return a |
||
return CreateClient(config, RedisClient::new); | ||
} | ||
|
||
@Override | ||
public CompletableFuture<Object> customCommand(String[] args) { | ||
public CompletableFuture<Object> customCommand(@NonNull String[] args) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct me if I'm wrong, but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct... and that would cause a protobuf builder error (NullPointerException). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so how would you solve this? |
||
return commandManager.submitNewCommand(CustomCommand, args, this::handleObjectResponse); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */ | ||
package glide.api.commands; | ||
|
||
import glide.api.models.configuration.RequestRoutingConfiguration.Route; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
/** | ||
* Connection Management Commands interface. | ||
* | ||
* @see: <a href="https://redis.io/commands/?group=connection">Connection Management Commands</a> | ||
*/ | ||
public interface ConnectionManagementClusterCommands { | ||
|
||
/** | ||
* Ping the Redis server. | ||
* | ||
* @see <a href="https://redis.io/commands/ping/">redis.io</a> for details. | ||
* @param route Routing configuration for the command. Client will route the command to the nodes | ||
* defined. | ||
* @return Response from Redis containing a <code>String</code> with "PONG". | ||
*/ | ||
CompletableFuture<String> ping(Route route); | ||
acarbonetto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Ping the Redis server. | ||
* | ||
* @see <a href="https://redis.io/commands/ping/">redis.io</a> for details. | ||
* @param str The ping argument that will be returned. | ||
* @param route Routing configuration for the command. Client will route the command to the nodes | ||
* defined. | ||
* @return Response from Redis containing a <code>String</code> with a copy of the argument <code> | ||
* str</code>. | ||
*/ | ||
CompletableFuture<String> ping(String str, Route route); | ||
acarbonetto marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */ | ||
package glide.api.commands; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
|
||
/** | ||
* Connection Management Commands interface. | ||
* | ||
* @see: <a href="https://redis.io/commands/?group=connection">Connection Management Commands</a> | ||
*/ | ||
public interface ConnectionManagementCommands { | ||
|
||
/** | ||
* Ping the Redis server. | ||
* | ||
* @see <a href="https://redis.io/commands/ping/">redis.io</a> for details. | ||
* @return Response from Redis containing a <code>String</code> with "PONG". | ||
*/ | ||
CompletableFuture<String> ping(); | ||
|
||
/** | ||
* Ping the Redis server. | ||
* | ||
* @see <a href="https://redis.io/commands/ping/">redis.io</a> for details. | ||
* @param str The ping argument that will be returned. | ||
* @return Response from Redis containing a <code>String</code> with a copy of the argument <code> | ||
* str</code>. | ||
*/ | ||
CompletableFuture<String> ping(String str); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @shachlanAmazon for the idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not private?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated in 2cbf558