From 4d158f920d63fa70a14f7dc7e6922ee930a5cb71 Mon Sep 17 00:00:00 2001 From: "bramwelbarack89@gmail.com" Date: Wed, 20 Aug 2025 11:59:39 +0300 Subject: [PATCH 1/3] clean PR --- .../client/lib/commands/LATENCY_RESET.spec.ts | 104 ++++++++++++++++++ packages/client/lib/commands/LATENCY_RESET.ts | 24 ++++ packages/client/lib/commands/index.ts | 3 + 3 files changed, 131 insertions(+) create mode 100644 packages/client/lib/commands/LATENCY_RESET.spec.ts create mode 100644 packages/client/lib/commands/LATENCY_RESET.ts diff --git a/packages/client/lib/commands/LATENCY_RESET.spec.ts b/packages/client/lib/commands/LATENCY_RESET.spec.ts new file mode 100644 index 0000000000..030d0d78e0 --- /dev/null +++ b/packages/client/lib/commands/LATENCY_RESET.spec.ts @@ -0,0 +1,104 @@ +import { strict as assert } from 'node:assert'; +import testUtils, { GLOBAL } from '../test-utils'; +import LATENCY_RESET, { LATENCY_EVENTS } from './LATENCY_RESET'; +import { parseArgs } from './generic-transformers'; + +describe('LATENCY RESET', function () { + + + it('transformArguments with no events', () => { + assert.deepEqual( + parseArgs(LATENCY_RESET), + [ + 'LATENCY', + 'RESET' + ] + ); + }); + + it('transformArguments with one event', () => { + assert.deepEqual( + parseArgs(LATENCY_RESET, LATENCY_EVENTS.COMMAND), + [ + 'LATENCY', + 'RESET', + 'command' + ] + ); + }); + + it('transformArguments with multiple events', () => { + assert.deepEqual( + parseArgs(LATENCY_RESET, LATENCY_EVENTS.COMMAND, LATENCY_EVENTS.FORK), + [ + 'LATENCY', + 'RESET', + 'command', + 'fork' + ] + ); + }); + + + testUtils.testWithClient('client.latencyReset', async client => { + + await client.configSet('latency-monitor-threshold', '1'); + + + await client.sendCommand(['DEBUG', 'SLEEP', '0.1']); + + + const latestLatencyBeforeReset = await client.latencyLatest(); + assert.ok(latestLatencyBeforeReset.length > 0, 'Expected latency events to be recorded before first reset.'); + assert.equal(latestLatencyBeforeReset[0][0], 'command', 'Expected "command" event to be recorded.'); + assert.ok(Number(latestLatencyBeforeReset[0][2]) >= 100, 'Expected latest latency for "command" to be at least 100ms.'); + + + const replyAll = await client.latencyReset(); + + assert.equal(typeof replyAll, 'number'); + assert.ok(replyAll >= 0); + + + const latestLatencyAfterAllReset = await client.latencyLatest(); + assert.deepEqual(latestLatencyAfterAllReset, [], 'Expected no latency events after resetting all.'); + + + await client.sendCommand(['DEBUG', 'SLEEP', '0.05']); + const latestLatencyBeforeSpecificReset = await client.latencyLatest(); + assert.ok(latestLatencyBeforeSpecificReset.length > 0, 'Expected latency events before specific reset.'); + + + const replySpecific = await client.latencyReset(LATENCY_EVENTS.COMMAND); + assert.equal(typeof replySpecific, 'number'); + assert.ok(replySpecific >= 0); + + + const latestLatencyAfterSpecificReset = await client.latencyLatest(); + assert.deepEqual(latestLatencyAfterSpecificReset, [], 'Expected no latency events after specific reset of "command".'); + + + await client.sendCommand(['DEBUG', 'SLEEP', '0.02']); + + + const latestLatencyBeforeMultipleReset = await client.latencyLatest(); + assert.ok(latestLatencyBeforeMultipleReset.length > 0, 'Expected latency events before multiple reset.'); + + + const replyMultiple = await client.latencyReset(LATENCY_EVENTS.COMMAND, LATENCY_EVENTS.FORK); + assert.equal(typeof replyMultiple, 'number'); + assert.ok(replyMultiple >= 0); + + const latestLatencyAfterMultipleReset = await client.latencyLatest(); + assert.deepEqual(latestLatencyAfterMultipleReset, [], 'Expected no latency events after multiple specified resets.'); + + }, { + + ...GLOBAL.SERVERS.OPEN, + clientOptions: { + socket: { + connectTimeout: 300000 + } + } + }); +}); diff --git a/packages/client/lib/commands/LATENCY_RESET.ts b/packages/client/lib/commands/LATENCY_RESET.ts new file mode 100644 index 0000000000..0efa576763 --- /dev/null +++ b/packages/client/lib/commands/LATENCY_RESET.ts @@ -0,0 +1,24 @@ +import { CommandParser } from '../client/parser'; +import { Command } from '../RESP/types'; +import { LATENCY_EVENTS, LatencyEvent } from './LATENCY_GRAPH'; + +export { LATENCY_EVENTS, LatencyEvent }; + +export default { + NOT_KEYED_COMMAND: true, + IS_READ_ONLY: false, + /** + * Constructs the LATENCY RESET command + * * @param parser - The command parser + * @param events - The latency events to reset. If not specified, all events are reset. + * @see https://redis.io/commands/latency-reset/ + */ + parseCommand(parser: CommandParser, ...events: Array) { + const args = ['LATENCY', 'RESET']; + if (events.length > 0) { + args.push(...events); + } + parser.push(...args); + }, + transformReply: undefined as unknown as () => number +} as const satisfies Command; diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index 4614c8b282..05c07bbf34 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -171,6 +171,7 @@ import LATENCY_DOCTOR from './LATENCY_DOCTOR'; import LATENCY_GRAPH from './LATENCY_GRAPH'; import LATENCY_HISTORY from './LATENCY_HISTORY'; import LATENCY_LATEST from './LATENCY_LATEST'; +import LATENCY_RESET from './LATENCY_RESET'; import LCS_IDX_WITHMATCHLEN from './LCS_IDX_WITHMATCHLEN'; import LCS_IDX from './LCS_IDX'; import LCS_LEN from './LCS_LEN'; @@ -706,6 +707,8 @@ export default { latencyHistory: LATENCY_HISTORY, LATENCY_LATEST, latencyLatest: LATENCY_LATEST, + LATENCY_RESET, + latencyReset: LATENCY_RESET, LCS_IDX_WITHMATCHLEN, lcsIdxWithMatchLen: LCS_IDX_WITHMATCHLEN, LCS_IDX, From bee93ac3258f9f0a5ec0562ce591f17c11bc26ad Mon Sep 17 00:00:00 2001 From: "bramwelbarack89@gmail.com" Date: Sat, 6 Sep 2025 10:03:02 +0300 Subject: [PATCH 2/3] feat: Address review comments on CLIENT_KILL export , issue #2805 --- packages/client/lib/commands/index.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index 05c07bbf34..e865339bfb 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -35,7 +35,7 @@ import CLIENT_GETNAME from './CLIENT_GETNAME'; import CLIENT_GETREDIR from './CLIENT_GETREDIR'; import CLIENT_ID from './CLIENT_ID'; import CLIENT_INFO from './CLIENT_INFO'; -import CLIENT_KILL from './CLIENT_KILL'; +import CLIENT_KILL, { CLIENT_KILL_FILTERS } from './CLIENT_KILL'; import CLIENT_LIST from './CLIENT_LIST'; import CLIENT_NO_EVICT from './CLIENT_NO-EVICT'; import CLIENT_NO_TOUCH from './CLIENT_NO-TOUCH'; @@ -51,7 +51,7 @@ import CLUSTER_COUNT_FAILURE_REPORTS from './CLUSTER_COUNT-FAILURE-REPORTS'; import CLUSTER_COUNTKEYSINSLOT from './CLUSTER_COUNTKEYSINSLOT'; import CLUSTER_DELSLOTS from './CLUSTER_DELSLOTS'; import CLUSTER_DELSLOTSRANGE from './CLUSTER_DELSLOTSRANGE'; -import CLUSTER_FAILOVER from './CLUSTER_FAILOVER'; +import CLUSTER_FAILOVER, { FAILOVER_MODES } from './CLUSTER_FAILOVER'; import CLUSTER_FLUSHSLOTS from './CLUSTER_FLUSHSLOTS'; import CLUSTER_FORGET from './CLUSTER_FORGET'; import CLUSTER_GETKEYSINSLOT from './CLUSTER_GETKEYSINSLOT'; @@ -67,13 +67,13 @@ import CLUSTER_REPLICATE from './CLUSTER_REPLICATE'; import CLUSTER_RESET from './CLUSTER_RESET'; import CLUSTER_SAVECONFIG from './CLUSTER_SAVECONFIG'; import CLUSTER_SET_CONFIG_EPOCH from './CLUSTER_SET-CONFIG-EPOCH'; -import CLUSTER_SETSLOT from './CLUSTER_SETSLOT'; +import CLUSTER_SETSLOT, { CLUSTER_SLOT_STATES } from './CLUSTER_SETSLOT'; import CLUSTER_SLOTS from './CLUSTER_SLOTS'; import COMMAND_COUNT from './COMMAND_COUNT'; import COMMAND_GETKEYS from './COMMAND_GETKEYS'; import COMMAND_GETKEYSANDFLAGS from './COMMAND_GETKEYSANDFLAGS'; import COMMAND_INFO from './COMMAND_INFO'; -import COMMAND_LIST from './COMMAND_LIST'; +import COMMAND_LIST, { COMMAND_LIST_FILTER_BY } from './COMMAND_LIST'; import COMMAND from './COMMAND'; import CONFIG_GET from './CONFIG_GET'; import CONFIG_RESETASTAT from './CONFIG_RESETSTAT'; @@ -117,7 +117,7 @@ import EXISTS from './EXISTS'; import EXPIRE from './EXPIRE'; import EXPIREAT from './EXPIREAT'; import EXPIRETIME from './EXPIRETIME'; -import FLUSHALL from './FLUSHALL'; +import FLUSHALL, { REDIS_FLUSH_MODES } from './FLUSHALL'; import FLUSHDB from './FLUSHDB'; import FCALL from './FCALL'; import FCALL_RO from './FCALL_RO'; @@ -362,6 +362,14 @@ import VSETATTR from './VSETATTR'; import VSIM from './VSIM'; import VSIM_WITHSCORES from './VSIM_WITHSCORES'; +export { + CLIENT_KILL_FILTERS, + FAILOVER_MODES, + CLUSTER_SLOT_STATES, + COMMAND_LIST_FILTER_BY, + REDIS_FLUSH_MODES +}; + export default { ACL_CAT, aclCat: ACL_CAT, From 8fcbd9c2908fc44aa534fd8357b282571fb388ea Mon Sep 17 00:00:00 2001 From: Nikolay Karadzhov Date: Tue, 7 Oct 2025 11:39:36 +0300 Subject: [PATCH 3/3] export enums in top level --- packages/client/index.ts | 4 +--- packages/client/lib/commands/index.ts | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/index.ts b/packages/client/index.ts index 2deb0c39b4..09426cb50a 100644 --- a/packages/client/index.ts +++ b/packages/client/index.ts @@ -31,9 +31,7 @@ export const createSentinel = RedisSentinel.create; export { GEO_REPLY_WITH, GeoReplyWith } from './lib/commands/GEOSEARCH_WITH'; -export { SetOptions } from './lib/commands/SET'; -export { REDIS_FLUSH_MODES } from './lib/commands/FLUSHALL'; +export { SetOptions, CLIENT_KILL_FILTERS, FAILOVER_MODES, CLUSTER_SLOT_STATES, COMMAND_LIST_FILTER_BY, REDIS_FLUSH_MODES } from './lib/commands' export { BasicClientSideCache, BasicPooledClientSideCache } from './lib/client/cache'; - diff --git a/packages/client/lib/commands/index.ts b/packages/client/lib/commands/index.ts index e865339bfb..54ede43d01 100644 --- a/packages/client/lib/commands/index.ts +++ b/packages/client/lib/commands/index.ts @@ -370,6 +370,8 @@ export { REDIS_FLUSH_MODES }; +export { SetOptions } from './SET'; + export default { ACL_CAT, aclCat: ACL_CAT,