Skip to content

Node: move BackoffStrategy configuration to BaseConfiguration + Added Jitter param #3792

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

Merged
merged 3 commits into from
May 27, 2025
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
48 changes: 48 additions & 0 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,14 @@ export type ReadFrom =
*
* - **Inflight Requests Limit**: Control the number of concurrent requests using `inflightRequestsLimit`.
*
* ### Reconnection Strategy
* - **Reconnection Strategy**: Customize how the client should attempt reconnections using `connectionBackoff`.
* - `numberOfRetries`: The maximum number of retry attempts with increasing delays.
* - After this limit is reached, the retry interval becomes constant.
* - `factor`: A multiplier applied to the base delay between retries (e.g., `500` means a 500ms base delay).
* - `exponentBase`: The exponential growth factor for delays (e.g., `2` means the delay doubles with each retry).
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

jitter precent

* - `jitterPercent`: An optional percentage of jitter to add to the delay (e.g., `30` means the final delay will vary randomly between 70% and 130% of the calculated delay).
*
* @example
* ```typescript
* const config: BaseClientConfiguration = {
Expand All @@ -597,6 +605,12 @@ export type ReadFrom =
* clientAz: 'us-east-1a',
* defaultDecoder: Decoder.String,
* inflightRequestsLimit: 1000,
* connectionBackoff: {
* numberOfRetries: 10, // Maximum retries before delay becomes constant
* factor: 500, // Base delay in milliseconds
* exponentBase: 2, // Delay doubles with each retry (2^N)
* jitterPercent: 20, // Optional jitter percentage
* },
* };
* ```
*/
Expand Down Expand Up @@ -682,6 +696,38 @@ export interface BaseClientConfiguration {
* ```
*/
clientAz?: string;

/**
* Strategy used to determine how and when to reconnect, in case of connection failures.
* The time between attempts grows exponentially, following the formula rand(0 ... factor * (exponentBase ^ N)), where N is the number of failed attempts,
* and rand(...) applies a jitter of up to `jitterPercent`% to introduce randomness and reduce retry storms.
* The client will attempt to reconnect indefinitely. Once the maximum value is reached, that will remain the time between retry attempts until a
* reconnect attempt is successful.
* If not set, a default backoff strategy will be used.
*/
connectionBackoff?: {
/**
* 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 succesful.
* Value must be an integer.
*/
numberOfRetries: number;
/**
* The multiplier that will be applied to the waiting time between each retry.
* Value must be an integer.
*/
factor: number;
/**
* The exponent base configured for the strategy.
* Value must be an integer.
*/
exponentBase: number;
/** The Jitter percent on the calculated duration.
* If not set, a default value will be used.
* Value is optional, and must be an integer.
*/
jitterPercent?: number;
};
}

/**
Expand Down Expand Up @@ -7801,6 +7847,7 @@ export class BaseClient {
const protocol = options.protocol as
| connection_request.ProtocolVersion
| undefined;

return {
protocol,
clientName: options.clientName,
Expand All @@ -7814,6 +7861,7 @@ export class BaseClient {
authenticationInfo,
inflightRequestsLimit: options.inflightRequestsLimit,
clientAz: options.clientAz ?? null,
connectionRetryStrategy: options.connectionBackoff,
};
}

Expand Down
38 changes: 2 additions & 36 deletions node/src/GlideClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,12 @@ export namespace GlideClientConfiguration {
* This configuration allows you to tailor the client's behavior when connecting to a standalone Valkey Glide server.
*
* - **Database Selection**: Use `databaseId` to specify which logical database to connect to.
* - **Reconnection Strategy**: Customize how the client should attempt reconnections using `connectionBackoff`.
* - `numberOfRetries`: The maximum number of retry attempts with increasing delays.
* - After this limit is reached, the retry interval becomes constant.
* - `factor`: A multiplier applied to the base delay between retries (e.g., `500` means a 500ms base delay).
* - `exponentBase`: The exponential growth factor for delays (e.g., `2` means the delay doubles with each retry).
* - **Pub/Sub Subscriptions**: Predefine Pub/Sub channels and patterns to subscribe to upon connection establishment.
*
* @example
* ```typescript
* const config: GlideClientConfiguration = {
* databaseId: 1,
* connectionBackoff: {
* numberOfRetries: 10, // Maximum retries before delay becomes constant
* factor: 500, // Base delay in milliseconds
* exponentBase: 2, // Delay doubles with each retry (2^N)
* },
* pubsubSubscriptions: {
* channelsAndPatterns: {
* [GlideClientConfiguration.PubSubChannelModes.Pattern]: new Set(['news.*']),
Expand All @@ -141,31 +131,6 @@ export type GlideClientConfiguration = BaseClientConfiguration & {
* index of the logical database to connect to.
*/
databaseId?: number;
/**
* Strategy used to determine how and when to reconnect, in case of connection failures.
* The time between attempts grows exponentially, to the formula rand(0 .. factor * (exponentBase ^ N)), where N is the number of failed attempts.
* The client will attempt to reconnect indefinitely. Once the maximum value is reached, that will remain the time between retry attempts until a
* reconnect attempt is succesful.
* If not set, a default backoff strategy will be used.
*/
connectionBackoff?: {
/**
* 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 succesful.
* Value must be an integer.
*/
numberOfRetries: number;
/**
* The multiplier that will be applied to the waiting time between each retry.
* Value must be an integer.
*/
factor: number;
/**
* The exponent base configured for the strategy.
* Value must be an integer.
*/
exponentBase: number;
};
/**
* PubSub subscriptions to be used for the client.
* Will be applied via SUBSCRIBE/PSUBSCRIBE commands during connection establishment.
Expand Down Expand Up @@ -206,7 +171,7 @@ export class GlideClient extends BaseClient {
): connection_request.IConnectionRequest {
const configuration = super.createClientRequest(options);
configuration.databaseId = options.databaseId;
configuration.connectionRetryStrategy = options.connectionBackoff;

this.configurePubsub(options, configuration);

if (options.advancedConfiguration) {
Expand Down Expand Up @@ -249,6 +214,7 @@ export class GlideClient extends BaseClient {
* numberOfRetries: 5,
* factor: 1000,
* exponentBase: 2,
* jitter: 20,
* },
* pubsubSubscriptions: {
* channelsAndPatterns: {
Expand Down
6 changes: 6 additions & 0 deletions node/src/GlideClusterClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,12 @@ export class GlideClusterClient extends BaseClient {
* console.log(`Received message: ${msg.payload}`);
* },
* },
* connectionBackoff: {
* numberOfRetries: 5,
* factor: 1000,
* exponentBase: 2,
* jitter: 20,
* },
* });
* ```
*
Expand Down
Loading