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

Node: Add binary variant to connection management commands. #2160

Merged
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#### Changes
* Node: Added/updated binary variant to connection management commands and WATCH/UNWATCH ([#2160](https://github.com/valkey-io/valkey-glide/pull/2160))
* Node: Added FUNCTION DUMP and FUNCTION RESTORE commands ([#2129](https://github.com/valkey-io/valkey-glide/pull/2129))
* Node: Added ZUNIONSTORE command ([#2145](https://github.com/valkey-io/valkey-glide/pull/2145))
* Node: Added XREADGROUP command ([#2124](https://github.com/valkey-io/valkey-glide/pull/2124))
Expand Down
6 changes: 4 additions & 2 deletions node/src/BaseClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6042,8 +6042,10 @@ export class BaseClient {
* console.log(result); // Output: null - null is returned when the watched key is modified before transaction execution.
* ```
*/
public async watch(keys: string[]): Promise<"OK"> {
return this.createWritePromise(createWatch(keys));
public async watch(keys: GlideString[]): Promise<"OK"> {
return this.createWritePromise(createWatch(keys), {
decoder: Decoder.String,
});
}

/**
Expand Down
4 changes: 2 additions & 2 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1864,7 +1864,7 @@ export function createZPopMax(
/**
* @internal
*/
export function createEcho(message: string): command_request.Command {
export function createEcho(message: GlideString): command_request.Command {
return createCommand(RequestType.Echo, [message]);
}

Expand Down Expand Up @@ -3629,7 +3629,7 @@ export function createRandomKey(): command_request.Command {
}

/** @internal */
export function createWatch(keys: string[]): command_request.Command {
export function createWatch(keys: GlideString[]): command_request.Command {
return createCommand(RequestType.Watch, keys);
}

Expand Down
68 changes: 44 additions & 24 deletions node/src/GlideClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,14 @@ export class GlideClient extends BaseClient {
});
}

/** Ping the Redis server.
/**
* Pings the Redis server.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
*
* @see {@link https://valkey.io/commands/ping/|valkey.io} for details.
*
* @param message - An optional message to include in the PING command.
* If not provided, the server will respond with "PONG".
* If provided, the server will respond with a copy of the message.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. If not set, the default decoder from the client config will be used.
* @param message - (Optional) A message to include in the PING command.
* If not provided, the server will respond with "PONG".
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
* If provided, the server will respond with a copy of the message.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
* @returns - "PONG" if `message` is not provided, otherwise return a copy of `message`.
*
* @example
Expand All @@ -246,12 +247,12 @@ export class GlideClient extends BaseClient {
* console.log(result); // Output: 'Hello'
* ```
*/
public async ping(options?: {
message?: GlideString;
decoder?: Decoder;
}): Promise<GlideString> {
return this.createWritePromise(createPing(options?.message), {
decoder: options?.decoder,
public async ping(message?: GlideString): Promise<GlideString> {
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
return this.createWritePromise(createPing(message), {
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
decoder:
!message || typeof message === "string"
? Decoder.String
: Decoder.Bytes,
});
}

Expand All @@ -266,11 +267,13 @@ export class GlideClient extends BaseClient {
return this.createWritePromise(createInfo(options));
}

/** Change the currently selected Redis database.
/**
* Changes the currently selected Redis database.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
*
* @see {@link https://valkey.io/commands/select/|valkey.io} for details.
*
* @param index - The index of the database to select.
* @returns A simple OK response.
* @returns A simple `"OK"` response.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
*
* @example
* ```typescript
Expand All @@ -280,13 +283,19 @@ export class GlideClient extends BaseClient {
* ```
*/
public async select(index: number): Promise<"OK"> {
return this.createWritePromise(createSelect(index));
return this.createWritePromise(createSelect(index), {
decoder: Decoder.String,
});
}

/** Get the name of the primary's connection.
/**
* Gets the name of the primary's connection.
*
* @see {@link https://valkey.io/commands/client-getname/|valkey.io} for more details.
*
* @returns the name of the client connection as a string if a name is set, or null if no name is assigned.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response.
* If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used.
* @returns The name of the client connection as a string if a name is set, or `null` if no name is assigned.
*
* @example
* ```typescript
Expand All @@ -295,8 +304,10 @@ export class GlideClient extends BaseClient {
* console.log(result); // Output: 'Client Name'
* ```
*/
public async clientGetName(): Promise<string | null> {
return this.createWritePromise(createClientGetName());
public async clientGetName(decoder?: Decoder): Promise<GlideString | null> {
return this.createWritePromise(createClientGetName(), {
decoder: decoder,
});
}

/** Rewrite the configuration file with the current configuration.
Expand Down Expand Up @@ -332,10 +343,12 @@ export class GlideClient extends BaseClient {
return this.createWritePromise(createConfigResetStat());
}

/** Returns the current connection id.
/**
* Returns the current connection ID.
*
* @see {@link https://valkey.io/commands/client-id/|valkey.io} for details.
*
* @returns the id of the client.
* @returns The ID of the client.
*/
public async clientId(): Promise<number> {
return this.createWritePromise(createClientId());
Expand Down Expand Up @@ -380,7 +393,9 @@ export class GlideClient extends BaseClient {
return this.createWritePromise(createConfigSet(parameters));
}

/** Echoes the provided `message` back.
/**
* Echoes the provided `message` back.
*
* @see {@link https://valkey.io/commands/echo|valkey.io} for more details.
*
* @param message - The message to be echoed back.
Expand All @@ -393,8 +408,11 @@ export class GlideClient extends BaseClient {
* console.log(echoedMessage); // Output: 'valkey-glide'
* ```
*/
public async echo(message: string): Promise<string> {
return this.createWritePromise(createEcho(message));
public async echo(message: GlideString): Promise<GlideString> {
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
return this.createWritePromise(createEcho(message), {
decoder:
typeof message === "string" ? Decoder.String : Decoder.Bytes,
});
}

/** Returns the server time
Expand Down Expand Up @@ -925,6 +943,8 @@ export class GlideClient extends BaseClient {
* ```
*/
public async unwatch(): Promise<"OK"> {
return this.createWritePromise(createUnWatch());
return this.createWritePromise(createUnWatch(), {
decoder: Decoder.String,
});
}
}
79 changes: 48 additions & 31 deletions node/src/GlideClusterClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,16 +406,16 @@ export class GlideClusterClient extends BaseClient {
);
}

/** Ping the Redis server.
/**
* Pings the Redis server.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
*
* @see {@link https://valkey.io/commands/ping/|valkey.io} for details.
*
* @param message - An optional message to include in the PING command.
* If not provided, the server will respond with "PONG".
* If provided, the server will respond with a copy of the message.
* @param route - The command will be routed to all primaries, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response. If not set, the default decoder from the client config will be used.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
* @param message - (Optional) A message to include in the PING command.
* If not provided, the server will respond with "PONG".
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
* If provided, the server will respond with a copy of the message.
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
* @param route - (Optional) The command will be routed to all primaries, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @returns - "PONG" if `message` is not provided, otherwise return a copy of `message`.
*
* @example
Expand All @@ -435,11 +435,13 @@ export class GlideClusterClient extends BaseClient {
public async ping(options?: {
message?: GlideString;
route?: Routes;
decoder?: Decoder;
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
}): Promise<GlideString> {
return this.createWritePromise(createPing(options?.message), {
route: toProtobufRoute(options?.route),
decoder: options?.decoder,
decoder:
!options?.message || typeof options?.message === "string"
? Decoder.String
: Decoder.Bytes,
});
}

Expand All @@ -463,15 +465,19 @@ export class GlideClusterClient extends BaseClient {
);
}

/** Get the name of the connection to which the request is routed.
/**
* Gets the name of the connection to which the request is routed.
*
* @see {@link https://valkey.io/commands/client-getname/|valkey.io} for details.
*
* @param route - The command will be routed a random node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @param route - (Optional) The command will be routed a random node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @param decoder - (Optional) {@link Decoder} type which defines how to handle the response.
* If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used.
*
* @returns - the name of the client connection as a string if a name is set, or null if no name is assigned.
* When specifying a route other than a single node, it returns a dictionary where each address is the key and
* its corresponding node response is the value.
* @returns - The name of the client connection as a string if a name is set, or `null` if no name is assigned.
* When specifying a route other than a single node, it returns a dictionary where each address is the key and
* its corresponding node response is the value.
*
* @example
* ```typescript
Expand All @@ -487,12 +493,16 @@ export class GlideClusterClient extends BaseClient {
* console.log(result); // Output: {'addr': 'Connection Name', 'addr2': 'Connection Name', 'addr3': 'Connection Name'}
* ```
*/
public async clientGetName(
route?: Routes,
): Promise<ClusterResponse<string | null>> {
return this.createWritePromise<ClusterResponse<string | null>>(
public async clientGetName(options?: {
route?: Routes;
decoder?: Decoder;
}): Promise<ClusterResponse<GlideString | null>> {
return this.createWritePromise<ClusterResponse<GlideString | null>>(
createClientGetName(),
{ route: toProtobufRoute(route) },
{
route: toProtobufRoute(options?.route),
decoder: options?.decoder,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:

...options

should accomplish the same thing

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

unfortunately, not, because both have route but in different type

},
);
}

Expand Down Expand Up @@ -536,13 +546,15 @@ export class GlideClusterClient extends BaseClient {
});
}

/** Returns the current connection id.
/**
* Returns the current connection ID.
*
* @see {@link https://valkey.io/commands/client-id/|valkey.io} for details.
*
* @param route - The command will be routed to a random node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @returns the id of the client. When specifying a route other than a single node,
* it returns a dictionary where each address is the key and its corresponding node response is the value.
* @param route - (Optional) The command will be routed to a random node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @returns The ID of the client. When specifying a route other than a single node,
* it returns a dictionary where each address is the key and its corresponding node response is the value.
*/
public async clientId(route?: Routes): Promise<ClusterResponse<number>> {
return this.createWritePromise<ClusterResponse<number>>(
Expand Down Expand Up @@ -611,14 +623,16 @@ export class GlideClusterClient extends BaseClient {
});
}

/** Echoes the provided `message` back.
/**
* Echoes the provided `message` back.
*
* @see {@link https://valkey.io/commands/echo/|valkey.io} for details.
*
* @param message - The message to be echoed back.
* @param route - The command will be routed to a random node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @param route - (Optional) The command will be routed to a random node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @returns The provided `message`. When specifying a route other than a single node,
* it returns a dictionary where each address is the key and its corresponding node response is the value.
* it returns a dictionary where each address is the key and its corresponding node response is the value.
*
* @example
* ```typescript
Expand All @@ -634,11 +648,13 @@ export class GlideClusterClient extends BaseClient {
* ```
*/
public async echo(
message: string,
message: GlideString,
route?: Routes,
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved
): Promise<ClusterResponse<string>> {
): Promise<ClusterResponse<GlideString>> {
return this.createWritePromise(createEcho(message), {
route: toProtobufRoute(route),
decoder:
typeof message === "string" ? Decoder.String : Decoder.Bytes,
});
}

Expand Down Expand Up @@ -1347,6 +1363,7 @@ export class GlideClusterClient extends BaseClient {
public async unwatch(route?: Routes): Promise<"OK"> {
return this.createWritePromise(createUnWatch(), {
route: toProtobufRoute(route),
decoder: Decoder.String,
});
}
}
4 changes: 3 additions & 1 deletion node/tests/GlideClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,9 @@ describe("GlideClient", () => {
expect(await client.get(key3)).toEqual("foobar");

// Transaction executes command successfully with unmodified watched keys
expect(await client.watch([key1, key2, key3])).toEqual("OK");
expect(await client.watch([key1, Buffer.from(key2), key3])).toEqual(
"OK",
);
results = await client.exec(setFoobarTransaction);
expect(results).toEqual(["OK", "OK", "OK"]);
// sanity check
Expand Down
4 changes: 3 additions & 1 deletion node/tests/GlideClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1585,7 +1585,9 @@ describe("GlideClusterClient", () => {

// Transaction executes command successfully with a read command on the watch key before
// transaction is executed.
expect(await client.watch([key1, key2, key3])).toEqual("OK");
expect(await client.watch([key1, key2, Buffer.from(key3)])).toEqual(
"OK",
);
expect(await client.get(key2)).toEqual("hello");
results = await client.exec(setFoobarTransaction);
expect(results).toEqual(["OK", "OK", "OK"]);
Expand Down
Loading
Loading