Skip to content

Commit d8db974

Browse files
authored
fix #1914 - CLIENT TRACKING (#2126)
1 parent 429b11e commit d8db974

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

packages/client/lib/client/commands.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import * as CLIENT_KILL from '../commands/CLIENT_KILL';
2424
import * as CLIENT_NO_EVICT from '../commands/CLIENT_NO-EVICT';
2525
import * as CLIENT_PAUSE from '../commands/CLIENT_PAUSE';
2626
import * as CLIENT_SETNAME from '../commands/CLIENT_SETNAME';
27+
import * as CLIENT_TRACKING from '../commands/CLIENT_TRACKING';
2728
import * as CLIENT_UNPAUSE from '../commands/CLIENT_UNPAUSE';
2829
import * as CLIENT_INFO from '../commands/CLIENT_INFO';
2930
import * as CLUSTER_ADDSLOTS from '../commands/CLUSTER_ADDSLOTS';
@@ -165,6 +166,8 @@ export default {
165166
clientPause: CLIENT_PAUSE,
166167
CLIENT_SETNAME,
167168
clientSetName: CLIENT_SETNAME,
169+
CLIENT_TRACKING,
170+
clientTracking: CLIENT_TRACKING,
168171
CLIENT_UNPAUSE,
169172
clientUnpause: CLIENT_UNPAUSE,
170173
CLIENT_INFO,
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { strict as assert } from 'assert';
2+
import testUtils, { GLOBAL } from '../test-utils';
3+
import { transformArguments } from './CLIENT_TRACKING';
4+
5+
describe('CLIENT TRACKING', () => {
6+
testUtils.isVersionGreaterThanHook([6]);
7+
8+
describe('transformArguments', () => {
9+
describe('true', () => {
10+
it('simple', () => {
11+
assert.deepEqual(
12+
transformArguments(true),
13+
['CLIENT', 'TRACKING', 'ON']
14+
);
15+
});
16+
17+
it('with REDIRECT', () => {
18+
assert.deepEqual(
19+
transformArguments(true, {
20+
REDIRECT: 1
21+
}),
22+
['CLIENT', 'TRACKING', 'ON', 'REDIRECT', '1']
23+
);
24+
});
25+
26+
describe('with BCAST', () => {
27+
it('simple', () => {
28+
assert.deepEqual(
29+
transformArguments(true, {
30+
BCAST: true
31+
}),
32+
['CLIENT', 'TRACKING', 'ON', 'BCAST']
33+
);
34+
});
35+
36+
describe('with PREFIX', () => {
37+
it('string', () => {
38+
assert.deepEqual(
39+
transformArguments(true, {
40+
BCAST: true,
41+
PREFIX: 'prefix'
42+
}),
43+
['CLIENT', 'TRACKING', 'ON', 'BCAST', 'PREFIX', 'prefix']
44+
);
45+
});
46+
47+
it('array', () => {
48+
assert.deepEqual(
49+
transformArguments(true, {
50+
BCAST: true,
51+
PREFIX: ['1', '2']
52+
}),
53+
['CLIENT', 'TRACKING', 'ON', 'BCAST', 'PREFIX', '1', 'PREFIX', '2']
54+
);
55+
});
56+
});
57+
});
58+
59+
it('with OPTIN', () => {
60+
assert.deepEqual(
61+
transformArguments(true, {
62+
OPTIN: true
63+
}),
64+
['CLIENT', 'TRACKING', 'ON', 'OPTIN']
65+
);
66+
});
67+
68+
it('with OPTOUT', () => {
69+
assert.deepEqual(
70+
transformArguments(true, {
71+
OPTOUT: true
72+
}),
73+
['CLIENT', 'TRACKING', 'ON', 'OPTOUT']
74+
);
75+
});
76+
77+
it('with NOLOOP', () => {
78+
assert.deepEqual(
79+
transformArguments(true, {
80+
NOLOOP: true
81+
}),
82+
['CLIENT', 'TRACKING', 'ON', 'NOLOOP']
83+
);
84+
});
85+
});
86+
87+
it('false', () => {
88+
assert.deepEqual(
89+
transformArguments(false),
90+
['CLIENT', 'TRACKING', 'OFF']
91+
);
92+
});
93+
});
94+
95+
testUtils.testWithClient('client.clientTracking', async client => {
96+
assert.equal(
97+
await client.clientTracking(false),
98+
'OK'
99+
);
100+
}, GLOBAL.SERVERS.OPEN);
101+
});
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { RedisCommandArgument, RedisCommandArguments } from '.';
2+
3+
interface CommonOptions {
4+
REDIRECT?: number;
5+
NOLOOP?: boolean;
6+
}
7+
8+
interface BroadcastOptions {
9+
BCAST?: boolean;
10+
PREFIX?: RedisCommandArgument | Array<RedisCommandArgument>;
11+
}
12+
13+
interface OptInOptions {
14+
OPTIN?: boolean;
15+
}
16+
17+
interface OptOutOptions {
18+
OPTOUT?: boolean;
19+
}
20+
21+
type ClientTrackingOptions = CommonOptions & (
22+
BroadcastOptions |
23+
OptInOptions |
24+
OptOutOptions
25+
);
26+
27+
export function transformArguments<M extends boolean>(
28+
mode: M,
29+
options?: M extends true ? ClientTrackingOptions : undefined
30+
): RedisCommandArguments {
31+
const args: RedisCommandArguments = [
32+
'CLIENT',
33+
'TRACKING',
34+
mode ? 'ON' : 'OFF'
35+
];
36+
37+
if (mode) {
38+
if (options?.REDIRECT) {
39+
args.push(
40+
'REDIRECT',
41+
options.REDIRECT.toString()
42+
);
43+
}
44+
45+
if (isBroadcast(options)) {
46+
args.push('BCAST');
47+
48+
if (options?.PREFIX) {
49+
if (Array.isArray(options.PREFIX)) {
50+
for (const prefix of options.PREFIX) {
51+
args.push('PREFIX', prefix);
52+
}
53+
} else {
54+
args.push('PREFIX', options.PREFIX);
55+
}
56+
}
57+
} else if (isOptIn(options)) {
58+
args.push('OPTIN');
59+
} else if (isOptOut(options)) {
60+
args.push('OPTOUT');
61+
}
62+
63+
if (options?.NOLOOP) {
64+
args.push('NOLOOP');
65+
}
66+
}
67+
68+
return args;
69+
}
70+
71+
function isBroadcast(options?: ClientTrackingOptions): options is BroadcastOptions {
72+
return (options as BroadcastOptions)?.BCAST === true;
73+
}
74+
75+
function isOptIn(options?: ClientTrackingOptions): options is OptInOptions {
76+
return (options as OptInOptions)?.OPTIN === true;
77+
}
78+
79+
function isOptOut(options?: ClientTrackingOptions): options is OptOutOptions {
80+
return (options as OptOutOptions)?.OPTOUT === true;
81+
}
82+
83+
export declare function transformReply(): 'OK' | Buffer;

0 commit comments

Comments
 (0)