Skip to content

Commit 4be30cc

Browse files
committed
comment cluster request & response policies (keep v4 behaver)
1 parent 67900a5 commit 4be30cc

14 files changed

+607
-553
lines changed

docs/clustering.md

-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@ createCluster({
105105
106106
## Command Routing
107107

108-
TODO request response policy
109-
110108
### Commands that operate on Redis Keys
111109

112110
Commands such as `GET`, `SET`, etc. are routed by the first key specified. For example `MGET 1 2 3` will be routed by the key `1`.

packages/client/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, CommandPolicies } from './lib/RESP/types';
1+
export { RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping/*, CommandPolicies*/ } from './lib/RESP/types';
22
export { RESP_TYPES } from './lib/RESP/decoder';
33
export { VerbatimString } from './lib/RESP/verbatim-string';
44
export { defineScript } from './lib/lua-script';

packages/client/lib/RESP/types.ts

+83-79
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,8 @@ export type ReplyWithTypeMapping<
200200
REPLY extends Array<infer T> ? Array<ReplyWithTypeMapping<T, TYPE_MAPPING>> :
201201
REPLY extends Set<infer T> ? Set<ReplyWithTypeMapping<T, TYPE_MAPPING>> :
202202
REPLY extends Map<infer K, infer V> ? Map<MapKey<K, TYPE_MAPPING>, ReplyWithTypeMapping<V, TYPE_MAPPING>> :
203-
// `Date` & `Buffer` are supersets of `Record`, so they need to be checked first
204-
REPLY extends Date ? REPLY :
205-
REPLY extends Buffer ? REPLY :
203+
// `Date | Buffer | Error` are supersets of `Record`, so they need to be checked first
204+
REPLY extends Date | Buffer | Error ? REPLY :
206205
REPLY extends Record<PropertyKey, any> ? {
207206
[P in keyof REPLY]: ReplyWithTypeMapping<REPLY[P], TYPE_MAPPING>;
208207
} :
@@ -222,57 +221,62 @@ export type RedisArgument = string | Buffer;
222221

223222
export type CommandArguments = Array<RedisArgument> & { preserve?: unknown };
224223

225-
export const REQUEST_POLICIES = {
226-
/**
227-
* TODO
228-
*/
229-
ALL_NODES: 'all_nodes',
230-
/**
231-
* TODO
232-
*/
233-
ALL_SHARDS: 'all_shards',
234-
/**
235-
* TODO
236-
*/
237-
SPECIAL: 'special'
238-
} as const;
239-
240-
export type REQUEST_POLICIES = typeof REQUEST_POLICIES;
241-
242-
export type RequestPolicies = REQUEST_POLICIES[keyof REQUEST_POLICIES];
243-
244-
export const RESPONSE_POLICIES = {
245-
/**
246-
* TODO
247-
*/
248-
ONE_SUCCEEDED: 'one_succeeded',
249-
/**
250-
* TODO
251-
*/
252-
ALL_SUCCEEDED: 'all_succeeded',
253-
/**
254-
* TODO
255-
*/
256-
LOGICAL_AND: 'agg_logical_and',
257-
/**
258-
* TODO
259-
*/
260-
SPECIAL: 'special'
261-
} as const;
262-
263-
export type RESPONSE_POLICIES = typeof RESPONSE_POLICIES;
264-
265-
export type ResponsePolicies = RESPONSE_POLICIES[keyof RESPONSE_POLICIES];
266-
267-
export type CommandPolicies = {
268-
request?: RequestPolicies | null;
269-
response?: ResponsePolicies | null;
270-
};
224+
// export const REQUEST_POLICIES = {
225+
// /**
226+
// * TODO
227+
// */
228+
// ALL_NODES: 'all_nodes',
229+
// /**
230+
// * TODO
231+
// */
232+
// ALL_SHARDS: 'all_shards',
233+
// /**
234+
// * TODO
235+
// */
236+
// SPECIAL: 'special'
237+
// } as const;
238+
239+
// export type REQUEST_POLICIES = typeof REQUEST_POLICIES;
240+
241+
// export type RequestPolicies = REQUEST_POLICIES[keyof REQUEST_POLICIES];
242+
243+
// export const RESPONSE_POLICIES = {
244+
// /**
245+
// * TODO
246+
// */
247+
// ONE_SUCCEEDED: 'one_succeeded',
248+
// /**
249+
// * TODO
250+
// */
251+
// ALL_SUCCEEDED: 'all_succeeded',
252+
// /**
253+
// * TODO
254+
// */
255+
// LOGICAL_AND: 'agg_logical_and',
256+
// /**
257+
// * TODO
258+
// */
259+
// SPECIAL: 'special'
260+
// } as const;
261+
262+
// export type RESPONSE_POLICIES = typeof RESPONSE_POLICIES;
263+
264+
// export type ResponsePolicies = RESPONSE_POLICIES[keyof RESPONSE_POLICIES];
265+
266+
// export type CommandPolicies = {
267+
// request?: RequestPolicies | null;
268+
// response?: ResponsePolicies | null;
269+
// };
271270

272271
export type Command = {
273272
FIRST_KEY_INDEX?: number | ((this: void, ...args: Array<any>) => RedisArgument | undefined);
274273
IS_READ_ONLY?: boolean;
275-
POLICIES?: CommandPolicies;
274+
/**
275+
* @internal
276+
* TODO: remove once `POLICIES` is implemented
277+
*/
278+
IS_FORWARD_COMMAND?: boolean;
279+
// POLICIES?: CommandPolicies;
276280
transformArguments(this: void, ...args: Array<any>): CommandArguments;
277281
TRANSFORM_LEGACY_REPLY?: boolean;
278282
transformReply: TransformReply | Record<RespVersions, TransformReply>;
@@ -355,32 +359,32 @@ export type CommandSignature<
355359
TYPE_MAPPING extends TypeMapping
356360
> = (...args: Parameters<COMMAND['transformArguments']>) => Promise<ReplyWithTypeMapping<CommandReply<COMMAND, RESP>, TYPE_MAPPING>>;
357361

358-
export type CommandWithPoliciesSignature<
359-
COMMAND extends Command,
360-
RESP extends RespVersions,
361-
TYPE_MAPPING extends TypeMapping,
362-
POLICIES extends CommandPolicies
363-
> = (...args: Parameters<COMMAND['transformArguments']>) => Promise<
364-
ReplyWithPolicy<
365-
ReplyWithTypeMapping<CommandReply<COMMAND, RESP>, TYPE_MAPPING>,
366-
MergePolicies<COMMAND, POLICIES>
367-
>
368-
>;
369-
370-
export type MergePolicies<
371-
COMMAND extends Command,
372-
POLICIES extends CommandPolicies
373-
> = Omit<COMMAND['POLICIES'], keyof POLICIES> & POLICIES;
374-
375-
type ReplyWithPolicy<
376-
REPLY,
377-
POLICIES extends CommandPolicies,
378-
> = (
379-
POLICIES['request'] extends REQUEST_POLICIES['SPECIAL'] ? never :
380-
POLICIES['request'] extends null | undefined ? REPLY :
381-
unknown extends POLICIES['request'] ? REPLY :
382-
POLICIES['response'] extends RESPONSE_POLICIES['SPECIAL'] ? never :
383-
POLICIES['response'] extends RESPONSE_POLICIES['ALL_SUCCEEDED' | 'ONE_SUCCEEDED' | 'LOGICAL_AND'] ? REPLY :
384-
// otherwise, return array of replies
385-
Array<REPLY>
386-
);
362+
// export type CommandWithPoliciesSignature<
363+
// COMMAND extends Command,
364+
// RESP extends RespVersions,
365+
// TYPE_MAPPING extends TypeMapping,
366+
// POLICIES extends CommandPolicies
367+
// > = (...args: Parameters<COMMAND['transformArguments']>) => Promise<
368+
// ReplyWithPolicy<
369+
// ReplyWithTypeMapping<CommandReply<COMMAND, RESP>, TYPE_MAPPING>,
370+
// MergePolicies<COMMAND, POLICIES>
371+
// >
372+
// >;
373+
374+
// export type MergePolicies<
375+
// COMMAND extends Command,
376+
// POLICIES extends CommandPolicies
377+
// > = Omit<COMMAND['POLICIES'], keyof POLICIES> & POLICIES;
378+
379+
// type ReplyWithPolicy<
380+
// REPLY,
381+
// POLICIES extends CommandPolicies,
382+
// > = (
383+
// POLICIES['request'] extends REQUEST_POLICIES['SPECIAL'] ? never :
384+
// POLICIES['request'] extends null | undefined ? REPLY :
385+
// unknown extends POLICIES['request'] ? REPLY :
386+
// POLICIES['response'] extends RESPONSE_POLICIES['SPECIAL'] ? never :
387+
// POLICIES['response'] extends RESPONSE_POLICIES['ALL_SUCCEEDED' | 'ONE_SUCCEEDED' | 'LOGICAL_AND'] ? REPLY :
388+
// // otherwise, return array of replies
389+
// Array<REPLY>
390+
// );

packages/client/lib/client/index.spec.ts

+24-16
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,19 @@ import { once } from 'node:events';
1111
// import { promisify } from 'node:util';
1212
import { MATH_FUNCTION, loadMathFunction } from '../commands/FUNCTION_LOAD.spec';
1313
import { RESP_TYPES } from '../RESP/decoder';
14+
import { NumberReply } from '../RESP/types';
1415
import { SortedSetMember } from '../commands/generic-transformers';
1516

1617
export const SQUARE_SCRIPT = defineScript({
17-
SCRIPT: 'return ARGV[1] * ARGV[1];',
18-
NUMBER_OF_KEYS: 0,
19-
transformArguments(number: number): Array<string> {
20-
return [number.toString()];
18+
SCRIPT:
19+
`local number = redis.call('GET', KEYS[1])
20+
return number * number`,
21+
NUMBER_OF_KEYS: 1,
22+
FIRST_KEY_INDEX: 0,
23+
transformArguments(key: string) {
24+
return [key];
2125
},
22-
transformReply: undefined as unknown as () => number
26+
transformReply: undefined as unknown as () => NumberReply
2327
});
2428

2529
describe('Client', () => {
@@ -214,9 +218,10 @@ describe('Client', () => {
214218
testUtils.testWithClient('with script', async client => {
215219
assert.deepEqual(
216220
await client.multi()
217-
.square(2)
221+
.set('key', '2')
222+
.square('key')
218223
.exec(),
219-
[4]
224+
['OK', 4]
220225
);
221226
}, {
222227
...GLOBAL.SERVERS.OPEN,
@@ -280,10 +285,12 @@ describe('Client', () => {
280285
});
281286

282287
testUtils.testWithClient('scripts', async client => {
283-
assert.equal(
284-
await client.square(2),
285-
4
286-
);
288+
const [, reply] = await Promise.all([
289+
client.set('key', '2'),
290+
client.square('key')
291+
]);
292+
293+
assert.equal(reply, 4);
287294
}, {
288295
...GLOBAL.SERVERS.OPEN,
289296
clientOptions: {
@@ -319,12 +326,13 @@ describe('Client', () => {
319326
});
320327

321328
testUtils.testWithClient('functions', async client => {
322-
await loadMathFunction(client);
329+
const [,, reply] = await Promise.all([
330+
loadMathFunction(client),
331+
client.set('key', '2'),
332+
client.math.square('key')
333+
]);
323334

324-
assert.equal(
325-
await client.math.square(2),
326-
4
327-
);
335+
assert.equal(reply, 4);
328336
}, {
329337
...GLOBAL.SERVERS.OPEN,
330338
minimumDockerVersion: [7, 0],

0 commit comments

Comments
 (0)