You've already forked node-redis
mirror of
https://github.com/redis/node-redis.git
synced 2025-08-06 02:15:48 +03:00
Support new cluster commands (#2050)
* Support new cluster commands * clean code Co-authored-by: leibale <leibale1998@gmail.com>
This commit is contained in:
@@ -23,8 +23,11 @@ import * as CLIENT_KILL from '../commands/CLIENT_KILL';
|
|||||||
import * as CLIENT_SETNAME from '../commands/CLIENT_SETNAME';
|
import * as CLIENT_SETNAME from '../commands/CLIENT_SETNAME';
|
||||||
import * as CLIENT_INFO from '../commands/CLIENT_INFO';
|
import * as CLIENT_INFO from '../commands/CLIENT_INFO';
|
||||||
import * as CLUSTER_ADDSLOTS from '../commands/CLUSTER_ADDSLOTS';
|
import * as CLUSTER_ADDSLOTS from '../commands/CLUSTER_ADDSLOTS';
|
||||||
|
import * as CLUSTER_ADDSLOTSRANGE from '../commands/CLUSTER_ADDSLOTSRANGE';
|
||||||
|
import * as CLUSTER_DELSLOTSRANGE from '../commands/CLUSTER_DELSLOTSRANGE';
|
||||||
import * as CLUSTER_FLUSHSLOTS from '../commands/CLUSTER_FLUSHSLOTS';
|
import * as CLUSTER_FLUSHSLOTS from '../commands/CLUSTER_FLUSHSLOTS';
|
||||||
import * as CLUSTER_INFO from '../commands/CLUSTER_INFO';
|
import * as CLUSTER_INFO from '../commands/CLUSTER_INFO';
|
||||||
|
import * as CLUSTER_LINKS from '../commands/CLUSTER_LINKS';
|
||||||
import * as CLUSTER_NODES from '../commands/CLUSTER_NODES';
|
import * as CLUSTER_NODES from '../commands/CLUSTER_NODES';
|
||||||
import * as CLUSTER_MEET from '../commands/CLUSTER_MEET';
|
import * as CLUSTER_MEET from '../commands/CLUSTER_MEET';
|
||||||
import * as CLUSTER_RESET from '../commands/CLUSTER_RESET';
|
import * as CLUSTER_RESET from '../commands/CLUSTER_RESET';
|
||||||
@@ -132,10 +135,16 @@ export default {
|
|||||||
clientInfo: CLIENT_INFO,
|
clientInfo: CLIENT_INFO,
|
||||||
CLUSTER_ADDSLOTS,
|
CLUSTER_ADDSLOTS,
|
||||||
clusterAddSlots: CLUSTER_ADDSLOTS,
|
clusterAddSlots: CLUSTER_ADDSLOTS,
|
||||||
|
CLUSTER_ADDSLOTSRANGE,
|
||||||
|
clusterAddSlotsRange: CLUSTER_ADDSLOTSRANGE,
|
||||||
|
CLUSTER_DELSLOTSRANGE,
|
||||||
|
clusterDelSlotsRange: CLUSTER_DELSLOTSRANGE,
|
||||||
CLUSTER_FLUSHSLOTS,
|
CLUSTER_FLUSHSLOTS,
|
||||||
clusterFlushSlots: CLUSTER_FLUSHSLOTS,
|
clusterFlushSlots: CLUSTER_FLUSHSLOTS,
|
||||||
CLUSTER_INFO,
|
CLUSTER_INFO,
|
||||||
clusterInfo: CLUSTER_INFO,
|
clusterInfo: CLUSTER_INFO,
|
||||||
|
CLUSTER_LINKS,
|
||||||
|
clusterLinks: CLUSTER_LINKS,
|
||||||
CLUSTER_NODES,
|
CLUSTER_NODES,
|
||||||
clusterNodes: CLUSTER_NODES,
|
clusterNodes: CLUSTER_NODES,
|
||||||
CLUSTER_MEET,
|
CLUSTER_MEET,
|
||||||
|
29
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts
Normal file
29
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_ADDSLOTSRANGE';
|
||||||
|
|
||||||
|
describe('CLUSTER ADDSLOTSRANGE', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('single', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments({
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}),
|
||||||
|
['CLUSTER', 'ADDSLOTSRANGE', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments([{
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}, {
|
||||||
|
start: 2,
|
||||||
|
end: 3
|
||||||
|
}]),
|
||||||
|
['CLUSTER', 'ADDSLOTSRANGE', '0', '1', '2', '3']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
13
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts
Normal file
13
packages/client/lib/commands/CLUSTER_ADDSLOTSRANGE.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
ranges: SlotRange | Array<SlotRange>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
return pushSlotRangesArguments(
|
||||||
|
['CLUSTER', 'ADDSLOTSRANGE'],
|
||||||
|
ranges
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
29
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts
Normal file
29
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.spec.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { transformArguments } from './CLUSTER_DELSLOTSRANGE';
|
||||||
|
|
||||||
|
describe('CLUSTER DELSLOTSRANGE', () => {
|
||||||
|
describe('transformArguments', () => {
|
||||||
|
it('single', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments({
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}),
|
||||||
|
['CLUSTER', 'DELSLOTSRANGE', '0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments([{
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}, {
|
||||||
|
start: 2,
|
||||||
|
end: 3
|
||||||
|
}]),
|
||||||
|
['CLUSTER', 'DELSLOTSRANGE', '0', '1', '2', '3']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
13
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts
Normal file
13
packages/client/lib/commands/CLUSTER_DELSLOTSRANGE.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { RedisCommandArguments } from '.';
|
||||||
|
import { pushSlotRangesArguments, SlotRange } from './generic-transformers';
|
||||||
|
|
||||||
|
export function transformArguments(
|
||||||
|
ranges: SlotRange | Array<SlotRange>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
return pushSlotRangesArguments(
|
||||||
|
['CLUSTER', 'DELSLOTSRANGE'],
|
||||||
|
ranges
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function transformReply(): 'OK';
|
27
packages/client/lib/commands/CLUSTER_LINKS.spec.ts
Normal file
27
packages/client/lib/commands/CLUSTER_LINKS.spec.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import testUtils, { GLOBAL } from '../test-utils';
|
||||||
|
import { transformArguments } from './CLUSTER_LINKS';
|
||||||
|
|
||||||
|
describe('CLUSTER LINKS', () => {
|
||||||
|
testUtils.isVersionGreaterThanHook([7, 0]);
|
||||||
|
|
||||||
|
it('transformArguments', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
transformArguments(),
|
||||||
|
['CLUSTER', 'LINKS']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testUtils.testWithCluster('clusterNode.clusterLinks', async cluster => {
|
||||||
|
const links = await cluster.getSlotMaster(0).client.clusterLinks();
|
||||||
|
assert.ok(Array.isArray(links));
|
||||||
|
for (const link of links) {
|
||||||
|
assert.equal(typeof link.direction, 'string');
|
||||||
|
assert.equal(typeof link.node, 'string');
|
||||||
|
assert.equal(typeof link.createTime, 'number');
|
||||||
|
assert.equal(typeof link.events, 'string');
|
||||||
|
assert.equal(typeof link.sendBufferAllocated, 'number');
|
||||||
|
assert.equal(typeof link.sendBufferUsed, 'number');
|
||||||
|
}
|
||||||
|
}, GLOBAL.CLUSTERS.OPEN);
|
||||||
|
});
|
38
packages/client/lib/commands/CLUSTER_LINKS.ts
Normal file
38
packages/client/lib/commands/CLUSTER_LINKS.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
export function transformArguments(): Array<string> {
|
||||||
|
return ['CLUSTER', 'LINKS'];
|
||||||
|
}
|
||||||
|
|
||||||
|
type ClusterLinksRawReply = Array<[
|
||||||
|
'direction',
|
||||||
|
string,
|
||||||
|
'node',
|
||||||
|
string,
|
||||||
|
'createTime',
|
||||||
|
number,
|
||||||
|
'events',
|
||||||
|
string,
|
||||||
|
'send-buffer-allocated',
|
||||||
|
number,
|
||||||
|
'send-buffer-used',
|
||||||
|
number
|
||||||
|
]>;
|
||||||
|
|
||||||
|
type ClusterLinksReply = Array<{
|
||||||
|
direction: string;
|
||||||
|
node: string;
|
||||||
|
createTime: number;
|
||||||
|
events: string;
|
||||||
|
sendBufferAllocated: number;
|
||||||
|
sendBufferUsed: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export function transformReply(reply: ClusterLinksRawReply): ClusterLinksReply {
|
||||||
|
return reply.map(peerLink => ({
|
||||||
|
direction: peerLink[1],
|
||||||
|
node: peerLink[3],
|
||||||
|
createTime: Number(peerLink[5]),
|
||||||
|
events: peerLink[7],
|
||||||
|
sendBufferAllocated: Number(peerLink[9]),
|
||||||
|
sendBufferUsed: Number(peerLink[11])
|
||||||
|
}));
|
||||||
|
}
|
@@ -23,7 +23,8 @@ import {
|
|||||||
pushOptionalVerdictArgument,
|
pushOptionalVerdictArgument,
|
||||||
transformCommandReply,
|
transformCommandReply,
|
||||||
CommandFlags,
|
CommandFlags,
|
||||||
CommandCategories
|
CommandCategories,
|
||||||
|
pushSlotRangesArguments
|
||||||
} from './generic-transformers';
|
} from './generic-transformers';
|
||||||
|
|
||||||
describe('Generic Transformers', () => {
|
describe('Generic Transformers', () => {
|
||||||
@@ -639,4 +640,29 @@ describe('Generic Transformers', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('pushSlotRangesArguments', () => {
|
||||||
|
it('single range', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
pushSlotRangesArguments([], {
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}),
|
||||||
|
['0', '1']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple ranges', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
pushSlotRangesArguments([], [{
|
||||||
|
start: 0,
|
||||||
|
end: 1
|
||||||
|
}, {
|
||||||
|
start: 2,
|
||||||
|
end: 3
|
||||||
|
}]),
|
||||||
|
['0', '1', '2', '3']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -422,3 +422,33 @@ export function transformCommandReply(
|
|||||||
categories: new Set(categories)
|
categories: new Set(categories)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SlotRange {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushSlotRangeArguments(
|
||||||
|
args: RedisCommandArguments,
|
||||||
|
range: SlotRange
|
||||||
|
): void {
|
||||||
|
args.push(
|
||||||
|
range.start.toString(),
|
||||||
|
range.end.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function pushSlotRangesArguments(
|
||||||
|
args: RedisCommandArguments,
|
||||||
|
ranges: SlotRange | Array<SlotRange>
|
||||||
|
): RedisCommandArguments {
|
||||||
|
if (Array.isArray(ranges)) {
|
||||||
|
for (const range of ranges) {
|
||||||
|
pushSlotRangeArguments(args, range);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pushSlotRangeArguments(args, ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user