Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: add FUNCTION FLUSH command #1700

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
* Python: Added FUNCTION LOAD command ([#1699](https://github.com/aws/glide-for-redis/pull/1699))
* Python: Added XPENDING command ([#1704](https://github.com/aws/glide-for-redis/pull/1704))
* Python: Added RANDOMKEY command ([#1701](https://github.com/aws/glide-for-redis/pull/1701))
* Python: Added FUNCTION FLUSH command ([#1700](https://github.com/aws/glide-for-redis/pull/1700))

### Breaking Changes
* Node: Update XREAD to return a Map of Map ([#1494](https://github.com/aws/glide-for-redis/pull/1494))
Expand Down
31 changes: 31 additions & 0 deletions python/python/glide/async_commands/cluster_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,37 @@ async def function_load(
),
)

async def function_flush(
self, mode: Optional[FlushMode] = None, route: Optional[Route] = None
) -> TOK:
"""
Deletes all function libraries.

See https://valkey.io/docs/latest/commands/function-flush/ for more details.

Args:
mode (Optional[FlushMode]): The flushing mode, could be either `SYNC` or `ASYNC`.
route (Optional[Route]): The command will be routed to all primaries, unless `route` is provided,
in which case the client will route the command to the nodes defined by `route`.

Returns:
TOK: A simple `OK`.

Examples:
>>> await client.function_flush(FlushMode.SYNC)
"OK"

Since: Redis 7.0.0.
"""
return cast(
TOK,
await self._execute_command(
RequestType.FunctionFlush,
[mode.value] if mode else [],
route,
),
)

async def time(self, route: Optional[Route] = None) -> TClusterResponse[List[str]]:
"""
Returns the server time.
Expand Down
26 changes: 26 additions & 0 deletions python/python/glide/async_commands/standalone_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,32 @@ async def function_load(self, library_code: str, replace: bool = False) -> str:
),
)

async def function_flush(self, mode: Optional[FlushMode] = None) -> TOK:
"""
Deletes all function libraries.

See https://valkey.io/docs/latest/commands/function-flush/ for more details.

Args:
mode (Optional[FlushMode]): The flushing mode, could be either `SYNC` or `ASYNC`.

Returns:
TOK: A simple `OK`.

Examples:
>>> await client.function_flush(FlushMode.SYNC)
"OK"

Since: Redis 7.0.0.
"""
return cast(
TOK,
await self._execute_command(
RequestType.FunctionFlush,
[mode.value] if mode else [],
),
)

async def time(self) -> List[str]:
"""
Returns the server time.
Expand Down
21 changes: 21 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,27 @@ def function_load(
["REPLACE", library_code] if replace else [library_code],
)

def function_flush(
self: TTransaction, mode: Optional[FlushMode] = None
) -> TTransaction:
"""
Deletes all function libraries.

See https://valkey.io/docs/latest/commands/function-flush/ for more details.

Args:
mode (Optional[FlushMode]): The flushing mode, could be either `SYNC` or `ASYNC`.

Commands response:
TOK: A simple `OK`.

Since: Redis 7.0.0.
"""
return self.append_command(
RequestType.FunctionFlush,
[mode.value] if mode else [],
)

def xadd(
self: TTransaction,
key: str,
Expand Down
60 changes: 60 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6731,6 +6731,66 @@ async def test_function_load_cluster_with_route(

assert await redis_client.function_load(new_code, True, route) == lib_name

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_function_flush(self, redis_client: TGlideClient):
min_version = "7.0.0"
if await check_if_server_version_lt(redis_client, min_version):
pytest.skip(f"Redis version required >= {min_version}")

lib_name = f"mylib1C{get_random_string(5)}"
func_name = f"myfunc1c{get_random_string(5)}"
code = generate_lua_lib_code(lib_name, {func_name: "return args[1]"}, True)

# Load the function
assert await redis_client.function_load(code) == lib_name

# TODO: Ensure the function exists with FUNCTION LIST

# Flush functions
assert await redis_client.function_flush(FlushMode.SYNC) == OK
assert await redis_client.function_flush(FlushMode.ASYNC) == OK

# TODO: Ensure the function is no longer present with FUNCTION LIST

# Attempt to re-load library without overwriting to ensure FLUSH was effective
assert await redis_client.function_load(code) == lib_name

# Clean up by flushing functions again
await redis_client.function_flush()

@pytest.mark.parametrize("cluster_mode", [True])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
@pytest.mark.parametrize("single_route", [True, False])
async def test_function_flush_with_routing(
self, redis_client: GlideClusterClient, single_route: bool
):
min_version = "7.0.0"
if await check_if_server_version_lt(redis_client, min_version):
pytest.skip(f"Redis version required >= {min_version}")

lib_name = f"mylib1C{get_random_string(5)}"
func_name = f"myfunc1c{get_random_string(5)}"
code = generate_lua_lib_code(lib_name, {func_name: "return args[1]"}, True)
route = SlotKeyRoute(SlotType.PRIMARY, "1") if single_route else AllPrimaries()

# Load the function
assert await redis_client.function_load(code, False, route) == lib_name

# TODO: Ensure the function exists with FUNCTION LIST

# Flush functions
assert await redis_client.function_flush(FlushMode.SYNC, route) == OK
assert await redis_client.function_flush(FlushMode.ASYNC, route) == OK

# TODO: Ensure the function is no longer present with FUNCTION LIST

# Attempt to re-load library without overwriting to ensure FLUSH was effective
assert await redis_client.function_load(code, False, route) == lib_name

# Clean up by flushing functions again
assert await redis_client.function_flush(route=route) == OK

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_srandmember(self, redis_client: TGlideClient):
Expand Down
6 changes: 6 additions & 0 deletions python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ async def transaction_test(
args.append(lib_name)
transaction.function_load(code, True)
args.append(lib_name)
transaction.function_flush()
args.append(OK)
transaction.function_flush(FlushMode.ASYNC)
args.append(OK)
transaction.function_flush(FlushMode.SYNC)
args.append(OK)

transaction.dbsize()
args.append(0)
Expand Down
Loading