Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Node: Added LOLWUT command ([#1934](https://github.com/valkey-io/valkey-glide/pull/1934))
* Node: Added LPOS command ([#1927](https://github.com/valkey-io/valkey-glide/pull/1927))
* Node: Added FUNCTION LOAD command ([#1969](https://github.com/valkey-io/valkey-glide/pull/1969))
* Node: Added FUNCTION FLUSH command ([#1984](https://github.com/valkey-io/valkey-glide/pull/1984))

## 1.0.0 (2024-07-09)

Expand Down
11 changes: 11 additions & 0 deletions node/src/Commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1566,6 +1566,17 @@ export function createFunctionLoad(
return createCommand(RequestType.FunctionLoad, args);
}

/**
* @internal
*/
export function createFunctionFlush(mode?: FlushMode): command_request.Command {
if (mode) {
return createCommand(RequestType.FunctionFlush, [mode.toString()]);
} else {
return createCommand(RequestType.FunctionFlush, []);
}
}

export type StreamReadOptions = {
/**
* If set, the read request will block for the set amount of milliseconds or
Expand Down
21 changes: 21 additions & 0 deletions node/src/GlideClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
createEcho,
createFlushAll,
createFlushDB,
createFunctionFlush,
createFunctionLoad,
createInfo,
createLolwut,
Expand Down Expand Up @@ -415,6 +416,26 @@ export class GlideClient extends BaseClient {
);
}

/**
* Deletes all function libraries.
*
* See https://valkey.io/commands/function-flush/ for details.
*
* since Valkey version 7.0.0.
*
* @param mode - The flushing mode, could be either {@link FlushMode.SYNC} or {@link FlushMode.ASYNC}.
* @returns A simple OK response.
*
* @example
* ```typescript
* const result = await client.functionFlush(FlushMode.SYNC);
* console.log(result); // Output: 'OK'
* ```
*/
public functionFlush(mode?: FlushMode): Promise<string> {
return this.createWritePromise(createFunctionFlush(mode));
}

/**
* Deletes all the keys of all the existing databases. This command never fails.
*
Expand Down
26 changes: 26 additions & 0 deletions node/src/GlideClusterClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
createEcho,
createFlushAll,
createFlushDB,
createFunctionFlush,
createFunctionLoad,
createInfo,
createLolwut,
Expand Down Expand Up @@ -689,6 +690,31 @@ export class GlideClusterClient extends BaseClient {
);
}

/**
* Deletes all function libraries.
*
* See https://valkey.io/commands/function-flush/ for details.
*
* since Valkey version 7.0.0.
*
* @param mode - The flushing mode, could be either {@link FlushMode.SYNC} or {@link FlushMode.ASYNC}.
* @param route - The command will be routed to all primary node, unless `route` is provided, in which
* case the client will route the command to the nodes defined by `route`.
* @returns A simple OK response.
*
* @example
* ```typescript
* const result = await client.functionFlush(FlushMode.SYNC);
* console.log(result); // Output: 'OK'
* ```
*/
public functionFlush(mode?: FlushMode, route?: Routes): Promise<string> {
return this.createWritePromise(
createFunctionFlush(mode),
toProtobufRoute(route),
);
}

/**
* Deletes all the keys of all the existing databases. This command never fails.
*
Expand Down
15 changes: 15 additions & 0 deletions node/src/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
createExpireAt,
createFlushAll,
createFlushDB,
createFunctionFlush,
createFunctionLoad,
createGeoAdd,
createGet,
Expand Down Expand Up @@ -1835,6 +1836,20 @@ export class BaseTransaction<T extends BaseTransaction<T>> {
return this.addAndReturn(createFunctionLoad(libraryCode, replace));
}

/**
* Deletes all function libraries.
*
* See https://valkey.io/commands/function-flush/ for details.
*
* since Valkey version 7.0.0.
*
* @param mode - The flushing mode, could be either {@link FlushMode.SYNC} or {@link FlushMode.ASYNC}.
* Command Response - `OK`.
*/
public functionFlush(mode?: FlushMode): T {
return this.addAndReturn(createFunctionFlush(mode));
}

/**
* Deletes all the keys of all the existing databases. This command never fails.
*
Expand Down
63 changes: 60 additions & 3 deletions node/tests/RedisClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
Transaction,
} from "..";
import { RedisCluster } from "../../utils/TestUtils.js";
import { FlushMode } from "../build-ts/src/commands/FlushMode.js";
import { command_request } from "../src/ProtobufMessage";
import { checkIfServerVersionLessThan, runBaseTests } from "./SharedTests";
import {
Expand All @@ -33,7 +34,6 @@ import {
parseEndpoints,
transactionTest,
} from "./TestUtilities";
import { FlushMode } from "../build-ts/src/commands/FlushMode.js";

/* eslint-disable @typescript-eslint/no-var-requires */

Expand Down Expand Up @@ -460,9 +460,66 @@ describe("GlideClient", () => {
]),
).toEqual(2);
} finally {
expect(await client.functionFlush()).toEqual("OK");
client.close();
}
},
);

it.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"function flush test_%p",
async (protocol) => {
if (await checkIfServerVersionLessThan("7.0.0")) return;

const client = await GlideClient.createClient(
getClientConfigurationOption(cluster.getAddresses(), protocol),
);

try {
const libName = "mylib1C" + uuidv4().replaceAll("-", "");
const funcName = "myfunc1c" + uuidv4().replaceAll("-", "");
const code = generateLuaLibCode(
libName,
new Map([[funcName, "return args[1]"]]),
true,
);

// TODO use commands instead of customCommand once implemented
// verify function does not yet exist
expect(
await client.customCommand(["FUNCTION", "FLUSH"]),
).toEqual("OK");
await client.customCommand([
"FUNCTION",
"LIST",
"LIBRARYNAME",
libName,
]),
).toEqual([]);

checkSimple(await client.functionLoad(code)).toEqual(libName);

// Flush functions
expect(await client.functionFlush(FlushMode.SYNC)).toEqual(
"OK",
);
expect(await client.functionFlush(FlushMode.ASYNC)).toEqual(
"OK",
);

// TODO use commands instead of customCommand once implemented
// verify function does not yet exist
expect(
await client.customCommand([
"FUNCTION",
"LIST",
"LIBRARYNAME",
libName,
]),
).toEqual([]);

// Attempt to re-load library without overwriting to ensure FLUSH was effective
checkSimple(await client.functionLoad(code)).toEqual(libName);
} finally {
expect(await client.functionFlush()).toEqual("OK");
client.close();
}
},
Expand Down
114 changes: 110 additions & 4 deletions node/tests/RedisClusterClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Routes,
} from "..";
import { RedisCluster } from "../../utils/TestUtils.js";
import { FlushMode } from "../build-ts/src/commands/FlushMode";
import { checkIfServerVersionLessThan, runBaseTests } from "./SharedTests";
import {
checkClusterResponse,
Expand All @@ -35,7 +36,6 @@ import {
parseEndpoints,
transactionTest,
} from "./TestUtilities";
import { FlushMode } from "../build-ts/src/commands/FlushMode";
type Context = {
client: GlideClusterClient;
};
Expand Down Expand Up @@ -675,12 +675,118 @@ describe("GlideClusterClient", () => {
(value) => expect(value).toEqual(2),
);
} finally {
expect(
expect(await client.functionFlush()).toEqual(
"OK",
);
client.close();
}
},
TIMEOUT,
);
},
);
},
);

describe.each([ProtocolVersion.RESP2, ProtocolVersion.RESP3])(
"Protocol is RESP2 = %s",
(protocol) => {
describe.each([true, false])(
"Single node route = %s",
(singleNodeRoute) => {
it(
"function flush",
async () => {
if (await checkIfServerVersionLessThan("7.0.0"))
return;

const client =
await GlideClusterClient.createClient(
getClientConfigurationOption(
cluster.getAddresses(),
protocol,
),
);

try {
const libName =
"mylib1C" + uuidv4().replaceAll("-", "");
const funcName =
"myfunc1c" + uuidv4().replaceAll("-", "");
const code = generateLuaLibCode(
libName,
new Map([[funcName, "return args[1]"]]),
true,
);
const route: Routes = singleNodeRoute
? { type: "primarySlotKey", key: "1" }
: "allPrimaries";

// TODO use commands instead of customCommand once implemented
// verify function does not yet exist
const functionList1 =
await client.customCommand([
"FUNCTION",
"FLUSH",
]),
"LIST",
"LIBRARYNAME",
libName,
]);
checkClusterResponse(
functionList1 as object,
singleNodeRoute,
(value) => expect(value).toEqual([]),
);

// load the library
checkSimple(
await client.functionLoad(
code,
undefined,
route,
),
).toEqual(libName);

// flush functions
expect(
await client.functionFlush(
FlushMode.SYNC,
route,
),
).toEqual("OK");
expect(
await client.functionFlush(
FlushMode.ASYNC,
route,
),
).toEqual("OK");

// TODO use commands instead of customCommand once implemented
// verify function does not exist
const functionList2 =
await client.customCommand([
"FUNCTION",
"LIST",
"LIBRARYNAME",
libName,
]);
checkClusterResponse(
functionList2 as object,
singleNodeRoute,
(value) => expect(value).toEqual([]),
);

// Attempt to re-load library without overwriting to ensure FLUSH was effective
checkSimple(
await client.functionLoad(
code,
undefined,
route,
),
).toEqual(libName);
} finally {
expect(await client.functionFlush()).toEqual(
"OK",
);
client.close();
}
},
Expand Down
10 changes: 8 additions & 2 deletions node/tests/TestUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import {
ReturnType,
Transaction,
} from "..";
import { checkIfServerVersionLessThan } from "./SharedTests";
import { FlushMode } from "../build-ts/src/commands/FlushMode";
import { LPosOptions } from "../build-ts/src/commands/LPosOptions";
import { GeospatialData } from "../build-ts/src/commands/geospatial/GeospatialData";
import { FlushMode } from "../build-ts/src/commands/FlushMode";
import { checkIfServerVersionLessThan } from "./SharedTests";

beforeAll(() => {
Logger.init("info");
Expand Down Expand Up @@ -654,6 +654,12 @@ export async function transactionTest(
args.push(libName);
baseTransaction.functionLoad(code, true);
args.push(libName);
baseTransaction.functionFlush();
args.push("OK");
baseTransaction.functionFlush(FlushMode.ASYNC);
args.push("OK");
baseTransaction.functionFlush(FlushMode.SYNC);
args.push("OK");
}

return args;
Expand Down