Skip to content

Commit

Permalink
Python: adds FUNCTION FLUSH command
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamazon committed Jun 18, 2024
1 parent 290b7af commit 752514c
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* Python: Added HSTRLEN command ([#1564](https://github.com/aws/glide-for-redis/pull/1564))
* Python: Added MSETNX command ([#1565](https://github.com/aws/glide-for-redis/pull/1565))
* Python: Added FUNCTION LOAD command ([#1589](https://github.com/aws/glide-for-redis/pull/1589))
* Python: Added FUNCTION FLUSH command ([#1590](https://github.com/aws/glide-for-redis/pull/1590))
* Python: Added MOVE command ([#1566](https://github.com/aws/glide-for-redis/pull/1566))
* Python: Added EXPIRETIME, PEXPIRETIME commands ([#1587](https://github.com/aws/glide-for-redis/pull/1587))
* Python: Added LSET command ([#1584](https://github.com/aws/glide-for-redis/pull/1584))
Expand Down
3 changes: 2 additions & 1 deletion python/python/glide/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0

from glide.async_commands.bitmap import BitmapIndexType, OffsetOptions
from glide.async_commands.command_args import Limit, ListDirection, OrderBy
from glide.async_commands.command_args import FlushMode, Limit, ListDirection, OrderBy
from glide.async_commands.core import (
ConditionalChange,
ExpireOptions,
Expand Down Expand Up @@ -103,6 +103,7 @@
"InfoSection",
"InsertPosition",
"json",
"FlushMode",
"LexBoundary",
"Limit",
"ListDirection",
Expand Down
33 changes: 32 additions & 1 deletion python/python/glide/async_commands/cluster_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from typing import Dict, List, Mapping, Optional, cast

from glide.async_commands.command_args import Limit, OrderBy
from glide.async_commands.command_args import FlushMode, Limit, OrderBy
from glide.async_commands.core import CoreCommands, InfoSection, _build_sort_args
from glide.async_commands.transaction import BaseTransaction, ClusterTransaction
from glide.constants import TOK, TClusterResponse, TResult, TSingleNodeRoute
Expand Down Expand Up @@ -314,6 +314,37 @@ async def echo(
await self._execute_command(RequestType.Echo, [message], route),
)

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 (FlushMode): The flushing mode, could be either `FlushMode.SYNC` or `FlushMode.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 function_load(
self, library_code: str, replace: bool = False, route: Optional[Route] = None
) -> str:
Expand Down
15 changes: 15 additions & 0 deletions python/python/glide/async_commands/command_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,18 @@ class ListDirection(Enum):
"""
RIGHT: Represents the option that elements should be popped from or added to the right side of a list.
"""


class FlushMode(Enum):
"""
Enumeration representing the flushing mode for `FLUSHALL`, `FLUSHDB` and `FUNCTION FLUSH` commands.
"""

SYNC = "SYNC"
"""
Represents synchronous flushing mode.
"""
ASYNC = "ASYNC"
"""
Represents asynchronous flushing mode.
"""
28 changes: 27 additions & 1 deletion python/python/glide/async_commands/standalone_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from typing import Dict, List, Mapping, Optional, cast

from glide.async_commands.command_args import Limit, OrderBy
from glide.async_commands.command_args import FlushMode, Limit, OrderBy
from glide.async_commands.core import CoreCommands, InfoSection, _build_sort_args
from glide.async_commands.transaction import BaseTransaction, Transaction
from glide.constants import TOK, TResult
Expand Down Expand Up @@ -228,6 +228,32 @@ async def echo(self, message: str) -> str:
"""
return cast(str, await self._execute_command(RequestType.Echo, [message]))

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 (FlushMode): The flushing mode, could be either `FlushMode.SYNC` or `FlushMode.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 function_load(self, library_code: str, replace: bool = False) -> str:
"""
Loads a library to Redis.
Expand Down
23 changes: 22 additions & 1 deletion python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import List, Mapping, Optional, Tuple, TypeVar, Union

from glide.async_commands.bitmap import OffsetOptions
from glide.async_commands.command_args import Limit, ListDirection, OrderBy
from glide.async_commands.command_args import FlushMode, Limit, ListDirection, OrderBy
from glide.async_commands.core import (
ConditionalChange,
ExpireOptions,
Expand Down Expand Up @@ -1823,6 +1823,27 @@ def xlen(self: TTransaction, key: str) -> TTransaction:
"""
return self.append_command(RequestType.XLen, [key])

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 (FlushMode): The flushing mode, could be either `FlushMode.SYNC` or `FlushMode.ASYNC`.
Commands response:
TOK: A simple `OK`.
Since: Redis 7.0.0.
"""
return self.append_command(
RequestType.FunctionFlush,
[mode.value] if mode else [],
)

def function_load(
self: TTransaction, library_code: str, replace: bool = False
) -> TTransaction:
Expand Down
62 changes: 61 additions & 1 deletion python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import pytest
from glide import ClosingError, RequestError, Script
from glide.async_commands.bitmap import BitmapIndexType, OffsetOptions
from glide.async_commands.command_args import Limit, ListDirection, OrderBy
from glide.async_commands.command_args import FlushMode, Limit, ListDirection, OrderBy
from glide.async_commands.core import (
ConditionalChange,
ExpireOptions,
Expand Down Expand Up @@ -5112,6 +5112,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: RedisClient):
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: RedisClusterClient, 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


class TestMultiKeyCommandCrossSlot:
@pytest.mark.parametrize("cluster_mode", [True])
Expand Down
8 changes: 7 additions & 1 deletion python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import pytest
from glide import RequestError
from glide.async_commands.bitmap import BitmapIndexType, OffsetOptions
from glide.async_commands.command_args import Limit, ListDirection, OrderBy
from glide.async_commands.command_args import FlushMode, Limit, ListDirection, OrderBy
from glide.async_commands.core import InsertPosition, StreamAddOptions, TrimByMinId
from glide.async_commands.sorted_set import (
AggregationType,
Expand Down Expand Up @@ -77,6 +77,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

0 comments on commit 752514c

Please sign in to comment.