forked from valkey-io/valkey-glide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Java: API layer with RedisClient (valkey-io#737)
* Java: API layer with RedisClient to create new client (#46) Signed-off-by: Andrew Carbonetto <[email protected]> --------- Signed-off-by: Yury-Fridlyand <[email protected]> Signed-off-by: Andrew Carbonetto <[email protected]> Co-authored-by: Yury-Fridlyand <[email protected]> Co-authored-by: SanHalacogluImproving <[email protected]>
- Loading branch information
1 parent
9d6010d
commit 2f901b0
Showing
18 changed files
with
816 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package glide.api; | ||
|
||
import glide.managers.CommandManager; | ||
import glide.managers.ConnectionManager; | ||
import java.util.concurrent.ExecutionException; | ||
import lombok.AllArgsConstructor; | ||
|
||
/** Base Client class for Redis */ | ||
@AllArgsConstructor | ||
public abstract class BaseClient implements AutoCloseable { | ||
|
||
protected ConnectionManager connectionManager; | ||
protected CommandManager commandManager; | ||
|
||
/** | ||
* Closes this resource, relinquishing any underlying resources. This method is invoked | ||
* automatically on objects managed by the try-with-resources statement. | ||
* | ||
* <p>see: <a | ||
* href="https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html#close--">AutoCloseable::close()</a> | ||
*/ | ||
@Override | ||
public void close() throws ExecutionException { | ||
try { | ||
connectionManager.closeConnection().get(); | ||
} catch (InterruptedException interruptedException) { | ||
// AutoCloseable classes are strongly advised to avoid throwing InterruptedExceptions | ||
// TODO: marking resources as closed: | ||
// https://github.com/orgs/Bit-Quill/projects/4/views/6?pane=issue&itemId=48063887 | ||
throw new RuntimeException(interruptedException); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package glide.api; | ||
|
||
import static glide.ffi.resolvers.SocketListenerResolver.getSocket; | ||
|
||
import glide.api.models.configuration.RedisClientConfiguration; | ||
import glide.connectors.handlers.CallbackDispatcher; | ||
import glide.connectors.handlers.ChannelHandler; | ||
import glide.managers.CommandManager; | ||
import glide.managers.ConnectionManager; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
/** | ||
* Async (non-blocking) client for Redis in Standalone mode. Use {@link | ||
* #CreateClient(RedisClientConfiguration)} to request a client to Redis. | ||
*/ | ||
public class RedisClient extends BaseClient { | ||
|
||
/** | ||
* Request an async (non-blocking) Redis client in Standalone mode. | ||
* | ||
* @param config - Redis Client Configuration | ||
* @return a Future to connect and return a RedisClient | ||
*/ | ||
public static CompletableFuture<RedisClient> CreateClient(RedisClientConfiguration config) { | ||
ChannelHandler channelHandler = buildChannelHandler(); | ||
ConnectionManager connectionManager = buildConnectionManager(channelHandler); | ||
CommandManager commandManager = buildCommandManager(channelHandler); | ||
// TODO: Support exception throwing, including interrupted exceptions | ||
return connectionManager | ||
.connectToRedis(config) | ||
.thenApply(ignore -> new RedisClient(connectionManager, commandManager)); | ||
} | ||
|
||
protected static ChannelHandler buildChannelHandler() { | ||
CallbackDispatcher callbackDispatcher = new CallbackDispatcher(); | ||
return new ChannelHandler(callbackDispatcher, getSocket()); | ||
} | ||
|
||
protected static ConnectionManager buildConnectionManager(ChannelHandler channelHandler) { | ||
return new ConnectionManager(channelHandler); | ||
} | ||
|
||
protected static CommandManager buildCommandManager(ChannelHandler channelHandler) { | ||
return new CommandManager(channelHandler); | ||
} | ||
|
||
protected RedisClient(ConnectionManager connectionManager, CommandManager commandManager) { | ||
super(connectionManager, commandManager); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
java/client/src/main/java/glide/api/models/configuration/BackoffStrategy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package glide.api.models.configuration; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NonNull; | ||
|
||
/** | ||
* Represents the strategy used to determine how and when to reconnect, in case of connection | ||
* failures. The time between attempts grows exponentially, to the formula <code>rand(0 ... factor * | ||
* (exponentBase ^ N))</code>, where <code>N</code> is the number of failed attempts. | ||
* | ||
* <p>Once the maximum value is reached, that will remain the time between retry attempts until a | ||
* reconnect attempt is successful. The client will attempt to reconnect indefinitely. | ||
*/ | ||
@Getter | ||
@Builder | ||
public class BackoffStrategy { | ||
/** | ||
* Number of retry attempts that the client should perform when disconnected from the server, | ||
* where the time between retries increases. Once the retries have reached the maximum value, the | ||
* time between retries will remain constant until a reconnect attempt is successful. | ||
*/ | ||
@NonNull private final Integer numOfRetries; | ||
|
||
/** The multiplier that will be applied to the waiting time between each retry. */ | ||
@NonNull private final Integer factor; | ||
|
||
/** The exponent base configured for the strategy. */ | ||
@NonNull private final Integer exponentBase; | ||
} |
54 changes: 54 additions & 0 deletions
54
java/client/src/main/java/glide/api/models/configuration/BaseClientConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package glide.api.models.configuration; | ||
|
||
import java.util.List; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NonNull; | ||
import lombok.Singular; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
/** | ||
* Configuration settings class for creating a Redis Client. Shared settings for standalone and | ||
* cluster clients. | ||
*/ | ||
@Getter | ||
@SuperBuilder | ||
public abstract class BaseClientConfiguration { | ||
/** | ||
* DNS Addresses and ports of known nodes in the cluster. If the server is in cluster mode the | ||
* list can be partial, as the client will attempt to map out the cluster and find all nodes. If | ||
* the server is in standalone mode, only nodes whose addresses were provided will be used by the | ||
* client. For example: <code>[ {address:sample-address-0001.use1.cache.amazonaws.com, port:6379}, | ||
* {address: sample-address-0002.use2.cache.amazonaws.com, port:6379} ]</code>. If none are set, a | ||
* default address localhost:6379 will be used. | ||
*/ | ||
@Singular private final List<NodeAddress> addresses; | ||
|
||
/** | ||
* True if communication with the cluster should use Transport Level Security. | ||
* | ||
* <p>If the server/cluster requires TLS, not setting this will cause the connection attempt to | ||
* fail. | ||
* | ||
* <p>If the server/cluster doesn't require TLS, setting this will also cause the connection | ||
* attempt to fail. | ||
*/ | ||
@Builder.Default private final boolean useTLS = false; | ||
|
||
/** Represents the client's read from strategy. */ | ||
@NonNull @Builder.Default private final ReadFrom readFrom = ReadFrom.PRIMARY; | ||
|
||
/** | ||
* Credentials for authentication process. If none are set, the client will not authenticate | ||
* itself with the server. | ||
*/ | ||
private final RedisCredentials credentials; | ||
|
||
/** | ||
* The duration in milliseconds that the client should wait for a request to complete. This | ||
* duration encompasses sending the request, awaiting for a response from the server, and any | ||
* required reconnections or retries. If the specified timeout is exceeded for a pending request, | ||
* it will result in a timeout error. If not set, a default value will be used. | ||
*/ | ||
private final Integer requestTimeout; | ||
} |
16 changes: 16 additions & 0 deletions
16
java/client/src/main/java/glide/api/models/configuration/NodeAddress.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package glide.api.models.configuration; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NonNull; | ||
|
||
/** Represents the address and port of a node in the cluster. */ | ||
@Getter | ||
@Builder | ||
public class NodeAddress { | ||
public static String DEFAULT_HOST = "localhost"; | ||
public static Integer DEFAULT_PORT = 6379; | ||
|
||
@NonNull @Builder.Default private final String host = DEFAULT_HOST; | ||
@NonNull @Builder.Default private final Integer port = DEFAULT_PORT; | ||
} |
12 changes: 12 additions & 0 deletions
12
java/client/src/main/java/glide/api/models/configuration/ReadFrom.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package glide.api.models.configuration; | ||
|
||
/** Represents the client's read from strategy. */ | ||
public enum ReadFrom { | ||
/** Always get from primary, in order to get the freshest data. */ | ||
PRIMARY, | ||
/** | ||
* Spread the requests between all replicas in a round-robin manner. If no replica is available, | ||
* route the requests to the primary. | ||
*/ | ||
PREFER_REPLICA | ||
} |
15 changes: 15 additions & 0 deletions
15
java/client/src/main/java/glide/api/models/configuration/RedisClientConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package glide.api.models.configuration; | ||
|
||
import lombok.Getter; | ||
import lombok.experimental.SuperBuilder; | ||
|
||
/** Represents the configuration settings for a Standalone Redis client. */ | ||
@Getter | ||
@SuperBuilder | ||
public class RedisClientConfiguration extends BaseClientConfiguration { | ||
/** Strategy used to determine how and when to reconnect, in case of connection failures. */ | ||
private final BackoffStrategy reconnectStrategy; | ||
|
||
/** Index of the logical database to connect to. */ | ||
private final Integer databaseId; | ||
} |
11 changes: 11 additions & 0 deletions
11
.../client/src/main/java/glide/api/models/configuration/RedisClusterClientConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package glide.api.models.configuration; | ||
|
||
import lombok.experimental.SuperBuilder; | ||
|
||
/** | ||
* Represents the configuration settings for a Cluster Redis client. Notes: Currently, the | ||
* reconnection strategy in cluster mode is not configurable, and exponential backoff with fixed | ||
* values is used. | ||
*/ | ||
@SuperBuilder | ||
public class RedisClusterClientConfiguration extends BaseClientConfiguration {} |
19 changes: 19 additions & 0 deletions
19
java/client/src/main/java/glide/api/models/configuration/RedisCredentials.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package glide.api.models.configuration; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NonNull; | ||
|
||
/** Represents the credentials for connecting to a Redis server. */ | ||
@Getter | ||
@Builder | ||
public class RedisCredentials { | ||
/** The password that will be used for authenticating connections to the Redis servers. */ | ||
@NonNull private final String password; | ||
|
||
/** | ||
* The username that will be used for authenticating connections to the Redis servers. If not | ||
* supplied, "default" will be used. | ||
*/ | ||
private final String username; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.