From 77664c31ffcc3f3248860b1e7bd8f8daec9246c3 Mon Sep 17 00:00:00 2001 From: Leibale Eidelman Date: Mon, 6 Sep 2021 16:02:53 -0400 Subject: [PATCH] Release 4.0.0-rc.1 (#1648) * update workflows & README * add .deepsource.toml * fix client.quit, add error events on cluster, fix some "deepsource.io" warnings * Release 4.0.0-rc.1 --- .deepsource.toml | 9 +++ .github/workflows/benchmark.yml | 3 +- .github/workflows/documentation.yml | 3 +- .github/workflows/tests.yml | 3 +- README.md | 4 +- lib/client.ts | 5 +- lib/cluster-slots.ts | 43 ++++------ lib/cluster.ts | 7 +- lib/commander.ts | 4 +- lib/commands-queue.ts | 13 ++- lib/commands/MIGRATE.ts | 2 +- lib/commands/generic-transformers.spec.ts | 1 - package-lock.json | 98 +++++++++++------------ package.json | 4 +- 14 files changed, 106 insertions(+), 93 deletions(-) create mode 100644 .deepsource.toml diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000000..72aefc7b07 --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,9 @@ +version = 1 + +[[analyzers]] +name = "javascript" +enabled = true + + [analyzers.meta] + environment = ["nodejs"] + dialect = "typescript" diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index b6e5802a91..2df438eb19 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -3,7 +3,8 @@ name: Benchmark on: push: branches: - - v4 + - master + - v4.0 jobs: benchmark: diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 16ca16b560..9575d4639b 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -3,7 +3,8 @@ name: Documentation on: push: branches: - - v4 + - master + - v4.0 jobs: documentation: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 028600f1a1..557d4f452d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,7 +3,8 @@ name: Tests on: push: branches: - - v4 + - master + - v4.0 jobs: tests: diff --git a/README.md b/README.md index acc229b69c..db0fa71cc7 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@

- - Coverage Status + + Coverage Status Downloads diff --git a/lib/client.ts b/lib/client.ts index a8da7f5ddd..ed06317c14 100644 --- a/lib/client.ts +++ b/lib/client.ts @@ -298,9 +298,10 @@ export default class RedisClient { - return this.#socket.quit(async () => { - this.#queue.addEncodedCommand(encodeCommand(['QUIT'])); + return this.#socket.quit(() => { + const promise = this.#queue.addEncodedCommand(encodeCommand(['QUIT'])); this.#tick(); + return promise; }); } diff --git a/lib/cluster-slots.ts b/lib/cluster-slots.ts index 3e255fc2a6..5fae5b9234 100644 --- a/lib/cluster-slots.ts +++ b/lib/cluster-slots.ts @@ -17,54 +17,40 @@ interface SlotNodes { clientIterator: IterableIterator> | undefined; } +type OnError = (err: unknown) => void; + export default class RedisClusterSlots { readonly #options: RedisClusterOptions; + readonly #onError: OnError; readonly #nodeByUrl = new Map>(); readonly #slots: Array> = []; - constructor(options: RedisClusterOptions) { + constructor(options: RedisClusterOptions, onError: OnError) { this.#options = options; + this.#onError = onError; } async connect(): Promise { for (const rootNode of this.#options.rootNodes) { - try { - await this.#discoverNodes(rootNode); - return; - } catch (err) { - console.error(err); - // this.emit('error', err); - } + if (await this.#discoverNodes(rootNode)) return; } throw new Error('None of the root nodes is available'); } async discover(startWith: RedisClientType): Promise { - try { - await this.#discoverNodes(startWith.options?.socket); - return; - } catch (err) { - console.error(err); - // this.emit('error', err); - } + if (await this.#discoverNodes(startWith.options?.socket)) return; for (const { client } of this.#nodeByUrl.values()) { if (client === startWith) continue; - - try { - await this.#discoverNodes(client.options?.socket); - return; - } catch (err) { - console.error(err); - // this.emit('error', err); - } + + if (await this.#discoverNodes(client.options?.socket)) return; } throw new Error('None of the cluster nodes is available'); } - async #discoverNodes(socketOptions?: RedisSocketOptions): Promise { + async #discoverNodes(socketOptions?: RedisSocketOptions): Promise { const client = RedisClient.create({ socket: socketOptions }); @@ -73,8 +59,14 @@ export default class RedisClusterSlots { rootNodes: Array; @@ -17,7 +18,7 @@ export interface RedisClusterOptions { export type RedisClusterType = WithPlugins & RedisCluster; -export default class RedisCluster { +export default class RedisCluster extends EventEmitter { static #extractFirstKey(command: RedisCommand, originalArgs: Array, redisArgs: Array): string | undefined { if (command.FIRST_KEY_INDEX === undefined) { return undefined; @@ -83,8 +84,10 @@ export default class RedisCluster) => RedisMultiCommandType; constructor(options: RedisClusterOptions) { + super(); + this.#options = options; - this.#slots = new RedisClusterSlots(options); + this.#slots = new RedisClusterSlots(options, err => this.emit('error', err)); this.#Multi = RedisMultiCommand.extend(options); } diff --git a/lib/commander.ts b/lib/commander.ts index 51adc417ba..e8ff91cc7b 100644 --- a/lib/commander.ts +++ b/lib/commander.ts @@ -97,12 +97,12 @@ export function transformCommandArguments( export function encodeCommand(args: Array): string { const encoded = [ `*${args.length}`, - `$${Buffer.byteLength(args[0])}`, + `$${Buffer.byteLength(args[0]).toString()}`, args[0] ]; for (let i = 1; i < args.length; i++) { - encoded.push(`$${Buffer.byteLength(args[i])}`, args[i]); + encoded.push(`$${Buffer.byteLength(args[i]).toString()}`, args[i]); } return encoded.join('\r\n') + '\r\n'; diff --git a/lib/commands-queue.ts b/lib/commands-queue.ts index 1890e0a00a..cae3fd6130 100644 --- a/lib/commands-queue.ts +++ b/lib/commands-queue.ts @@ -12,6 +12,7 @@ export interface QueueCommandOptions { interface CommandWaitingToBeSent extends CommandWaitingForReply { encodedCommand: string; + byteLength: number; chainId?: symbol; abort?: { signal: any; // TODO: `AbortSignal` type is incorrect @@ -130,6 +131,7 @@ export default class RedisCommandsQueue { return new Promise((resolve, reject) => { const node = new LinkedList.Node({ encodedCommand, + byteLength: Buffer.byteLength(encodedCommand), chainId: options?.chainId, resolve, reject @@ -156,7 +158,7 @@ export default class RedisCommandsQueue { this.#waitingToBeSent.pushNode(node); } - this.#waitingToBeSentCommandsLength += encodedCommand.length; + this.#waitingToBeSentCommandsLength += node.value.byteLength; }); } @@ -230,8 +232,12 @@ export default class RedisCommandsQueue { } this.#pubSubState[inProgressKey] += channelsCounter; + + const encodedCommand = encodeCommand(commandArgs), + byteLength = Buffer.byteLength(encodedCommand); this.#waitingToBeSent.push({ - encodedCommand: encodeCommand(commandArgs), + encodedCommand, + byteLength, channelsCounter, resolve: () => { this.#pubSubState[inProgressKey] -= channelsCounter; @@ -243,6 +249,7 @@ export default class RedisCommandsQueue { reject(); } }); + this.#waitingToBeSentCommandsLength += byteLength; }); } @@ -268,7 +275,7 @@ export default class RedisCommandsQueue { lastCommandChainId: symbol | undefined; for (const command of this.#waitingToBeSent) { encoded.push(command.encodedCommand); - size += command.encodedCommand.length; + size += command.byteLength; if (size > recommendedSize) { lastCommandChainId = command.chainId; break; diff --git a/lib/commands/MIGRATE.ts b/lib/commands/MIGRATE.ts index 1d2fc075ef..14dbe741be 100644 --- a/lib/commands/MIGRATE.ts +++ b/lib/commands/MIGRATE.ts @@ -19,7 +19,7 @@ export function transformArguments( isKeyString = typeof key === 'string'; if (isKeyString) { - args.push(key as string); + args.push(key); } else { args.push('""'); } diff --git a/lib/commands/generic-transformers.spec.ts b/lib/commands/generic-transformers.spec.ts index 5335255f91..9ac72bb1b2 100644 --- a/lib/commands/generic-transformers.spec.ts +++ b/lib/commands/generic-transformers.spec.ts @@ -1,5 +1,4 @@ import { strict as assert } from 'assert'; -import { isObject } from 'util'; import { transformReplyBoolean, transformReplyBooleanArray, diff --git a/package-lock.json b/package-lock.json index 3b7397b61e..ac623c60e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "redis", - "version": "4.0.0-rc.0", + "version": "4.0.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "redis", - "version": "4.0.0-rc.0", + "version": "4.0.0-rc.1", "license": "MIT", "dependencies": { "cluster-key-slot": "1.1.0", @@ -17,7 +17,7 @@ "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", "@types/mocha": "^9.0.0", - "@types/node": "^16.7.8", + "@types/node": "^16.7.10", "@types/sinon": "^10.0.2", "@types/which": "^2.0.1", "@types/yallist": "^4.0.1", @@ -642,9 +642,9 @@ } }, "node_modules/@octokit/graphql": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.7.0.tgz", - "integrity": "sha512-diY0qMPyQjfu4rDu3kDhJ9qIZadIm4IISO3RJSv9ajYUWJUCO0AykbgzLcg1xclxtXgzY583u3gAv66M6zz5SA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", "dev": true, "dependencies": { "@octokit/request": "^5.6.0", @@ -653,18 +653,18 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-9.7.0.tgz", - "integrity": "sha512-TUJ16DJU8mekne6+KVcMV5g6g/rJlrnIKn7aALG9QrNpnEipFc1xjoarh0PKaAWf2Hf+HwthRKYt+9mCm5RsRg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-10.0.0.tgz", + "integrity": "sha512-k1iO2zKuEjjRS1EJb4FwSLk+iF6EGp+ZV0OMRViQoWhQ1fZTk9hg1xccZII5uyYoiqcbC73MRBmT45y1vp2PPg==", "dev": true }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.15.1.tgz", - "integrity": "sha512-47r52KkhQDkmvUKZqXzA1lKvcyJEfYh3TKAIe5+EzMeyDM3d+/s5v11i2gTk8/n6No6DPi3k5Ind6wtDbo/AEg==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.0.tgz", + "integrity": "sha512-8YYzALPMvEZ35kgy5pdYvQ22Roz+BIuEaedO575GwE2vb/ACDqQn0xQrTJR4tnZCJn7pi8+AWPVjrFDaERIyXQ==", "dev": true, "dependencies": { - "@octokit/types": "^6.24.0" + "@octokit/types": "^6.26.0" }, "peerDependencies": { "@octokit/core": ">=2" @@ -730,12 +730,12 @@ } }, "node_modules/@octokit/types": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.25.0.tgz", - "integrity": "sha512-bNvyQKfngvAd/08COlYIN54nRgxskmejgywodizQNyiKoXmWRAjKup2/LYwm+T9V0gsKH6tuld1gM0PzmOiB4Q==", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.26.0.tgz", + "integrity": "sha512-RDxZBAFMtqs1ZPnbUu1e7ohPNfoNhTiep4fErY7tZs995BeHu369Vsh5woMIaFbllRWEZBfvTCS4hvDnMPiHrA==", "dev": true, "dependencies": { - "@octokit/openapi-types": "^9.5.0" + "@octokit/openapi-types": "^10.0.0" } }, "node_modules/@sindresorhus/is": { @@ -855,9 +855,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.8.tgz", - "integrity": "sha512-8upnoQU0OPzbIkm+ZMM0zCeFCkw2s3mS0IWdx0+AAaWqm4fkBb0UJp8Edl7FVKRamYbpJC/aVsHpKWBIbiC7Zg==", + "version": "16.7.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz", + "integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==", "dev": true }, "node_modules/@types/parse-json": { @@ -1845,9 +1845,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.3.822", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.822.tgz", - "integrity": "sha512-k7jG5oYYHxF4jx6PcqwHX3JVME/OjzolqOZiIogi9xtsfsmTjTdie4x88OakYFPEa8euciTgCCzvVNwvmjHb1Q==", + "version": "1.3.827", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.827.tgz", + "integrity": "sha512-ye+4uQOY/jbjRutMcE/EmOcNwUeo1qo9aKL2tPyb09cU3lmxNeyDF4RWiemmkknW+p29h7dyDqy02higTxc9/A==", "dev": true }, "node_modules/emoji-regex": { @@ -4773,9 +4773,9 @@ } }, "node_modules/shiki": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.8.tgz", - "integrity": "sha512-499zQUTjcNTVwwiaPrWldUTXIV3T9HZWxDwE82bY+9GE7P2uD6hpHUTXNbTof3iOG6WT+/062+OMbl0lDoG8WQ==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.10.tgz", + "integrity": "sha512-xeM7Oc6hY+6iW5O/T5hor8ul7mEprzyl5y4r5zthEHToQNw7MIhREMgU3r2gKDB0NaMLNrkcEQagudCdzE13Lg==", "dev": true, "dependencies": { "json5": "^2.2.0", @@ -6164,9 +6164,9 @@ } }, "@octokit/graphql": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.7.0.tgz", - "integrity": "sha512-diY0qMPyQjfu4rDu3kDhJ9qIZadIm4IISO3RJSv9ajYUWJUCO0AykbgzLcg1xclxtXgzY583u3gAv66M6zz5SA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", "dev": true, "requires": { "@octokit/request": "^5.6.0", @@ -6175,18 +6175,18 @@ } }, "@octokit/openapi-types": { - "version": "9.7.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-9.7.0.tgz", - "integrity": "sha512-TUJ16DJU8mekne6+KVcMV5g6g/rJlrnIKn7aALG9QrNpnEipFc1xjoarh0PKaAWf2Hf+HwthRKYt+9mCm5RsRg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-10.0.0.tgz", + "integrity": "sha512-k1iO2zKuEjjRS1EJb4FwSLk+iF6EGp+ZV0OMRViQoWhQ1fZTk9hg1xccZII5uyYoiqcbC73MRBmT45y1vp2PPg==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.15.1.tgz", - "integrity": "sha512-47r52KkhQDkmvUKZqXzA1lKvcyJEfYh3TKAIe5+EzMeyDM3d+/s5v11i2gTk8/n6No6DPi3k5Ind6wtDbo/AEg==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.0.tgz", + "integrity": "sha512-8YYzALPMvEZ35kgy5pdYvQ22Roz+BIuEaedO575GwE2vb/ACDqQn0xQrTJR4tnZCJn7pi8+AWPVjrFDaERIyXQ==", "dev": true, "requires": { - "@octokit/types": "^6.24.0" + "@octokit/types": "^6.26.0" } }, "@octokit/plugin-request-log": { @@ -6244,12 +6244,12 @@ } }, "@octokit/types": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.25.0.tgz", - "integrity": "sha512-bNvyQKfngvAd/08COlYIN54nRgxskmejgywodizQNyiKoXmWRAjKup2/LYwm+T9V0gsKH6tuld1gM0PzmOiB4Q==", + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.26.0.tgz", + "integrity": "sha512-RDxZBAFMtqs1ZPnbUu1e7ohPNfoNhTiep4fErY7tZs995BeHu369Vsh5woMIaFbllRWEZBfvTCS4hvDnMPiHrA==", "dev": true, "requires": { - "@octokit/openapi-types": "^9.5.0" + "@octokit/openapi-types": "^10.0.0" } }, "@sindresorhus/is": { @@ -6360,9 +6360,9 @@ "dev": true }, "@types/node": { - "version": "16.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.8.tgz", - "integrity": "sha512-8upnoQU0OPzbIkm+ZMM0zCeFCkw2s3mS0IWdx0+AAaWqm4fkBb0UJp8Edl7FVKRamYbpJC/aVsHpKWBIbiC7Zg==", + "version": "16.7.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.10.tgz", + "integrity": "sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==", "dev": true }, "@types/parse-json": { @@ -7108,9 +7108,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.822", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.822.tgz", - "integrity": "sha512-k7jG5oYYHxF4jx6PcqwHX3JVME/OjzolqOZiIogi9xtsfsmTjTdie4x88OakYFPEa8euciTgCCzvVNwvmjHb1Q==", + "version": "1.3.827", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.827.tgz", + "integrity": "sha512-ye+4uQOY/jbjRutMcE/EmOcNwUeo1qo9aKL2tPyb09cU3lmxNeyDF4RWiemmkknW+p29h7dyDqy02higTxc9/A==", "dev": true }, "emoji-regex": { @@ -9284,9 +9284,9 @@ } }, "shiki": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.8.tgz", - "integrity": "sha512-499zQUTjcNTVwwiaPrWldUTXIV3T9HZWxDwE82bY+9GE7P2uD6hpHUTXNbTof3iOG6WT+/062+OMbl0lDoG8WQ==", + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.9.10.tgz", + "integrity": "sha512-xeM7Oc6hY+6iW5O/T5hor8ul7mEprzyl5y4r5zthEHToQNw7MIhREMgU3r2gKDB0NaMLNrkcEQagudCdzE13Lg==", "dev": true, "requires": { "json5": "^2.2.0", diff --git a/package.json b/package.json index fd309d970f..56a7ed38c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redis", - "version": "4.0.0-rc.0", + "version": "4.0.0-rc.1", "description": "A high performance Redis client.", "keywords": [ "database", @@ -35,7 +35,7 @@ "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", "@types/mocha": "^9.0.0", - "@types/node": "^16.7.8", + "@types/node": "^16.7.10", "@types/sinon": "^10.0.2", "@types/which": "^2.0.1", "@types/yallist": "^4.0.1",