coredis 4.23.1__py3-none-any.whl → 5.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of coredis might be problematic. Click here for more details.
- coredis/__init__.py +1 -3
- coredis/_packer.py +10 -10
- coredis/_protocols.py +23 -32
- coredis/_py_311_typing.py +20 -0
- coredis/_py_312_typing.py +17 -0
- coredis/_utils.py +49 -51
- coredis/_version.py +3 -3
- coredis/cache.py +57 -82
- coredis/client/__init__.py +1 -2
- coredis/client/basic.py +129 -56
- coredis/client/cluster.py +147 -70
- coredis/commands/__init__.py +27 -7
- coredis/commands/_key_spec.py +11 -10
- coredis/commands/_utils.py +1 -1
- coredis/commands/_validators.py +30 -20
- coredis/commands/_wrappers.py +19 -99
- coredis/commands/bitfield.py +10 -2
- coredis/commands/constants.py +20 -3
- coredis/commands/core.py +1627 -1246
- coredis/commands/function.py +29 -22
- coredis/commands/monitor.py +0 -71
- coredis/commands/pubsub.py +7 -142
- coredis/commands/request.py +108 -0
- coredis/commands/script.py +9 -9
- coredis/commands/sentinel.py +60 -49
- coredis/connection.py +14 -15
- coredis/exceptions.py +2 -2
- coredis/experimental/__init__.py +0 -4
- coredis/globals.py +3 -0
- coredis/modules/autocomplete.py +28 -30
- coredis/modules/base.py +15 -31
- coredis/modules/filters.py +269 -245
- coredis/modules/graph.py +61 -62
- coredis/modules/json.py +172 -140
- coredis/modules/response/_callbacks/autocomplete.py +5 -4
- coredis/modules/response/_callbacks/graph.py +34 -29
- coredis/modules/response/_callbacks/json.py +5 -3
- coredis/modules/response/_callbacks/search.py +49 -53
- coredis/modules/response/_callbacks/timeseries.py +18 -30
- coredis/modules/response/types.py +1 -5
- coredis/modules/search.py +186 -169
- coredis/modules/timeseries.py +184 -164
- coredis/parser.py +6 -19
- coredis/pipeline.py +391 -422
- coredis/pool/basic.py +7 -7
- coredis/pool/cluster.py +3 -3
- coredis/pool/nodemanager.py +10 -3
- coredis/response/_callbacks/__init__.py +76 -57
- coredis/response/_callbacks/acl.py +0 -3
- coredis/response/_callbacks/cluster.py +25 -16
- coredis/response/_callbacks/command.py +8 -6
- coredis/response/_callbacks/connection.py +4 -3
- coredis/response/_callbacks/geo.py +17 -13
- coredis/response/_callbacks/hash.py +13 -11
- coredis/response/_callbacks/keys.py +9 -5
- coredis/response/_callbacks/module.py +2 -3
- coredis/response/_callbacks/script.py +6 -8
- coredis/response/_callbacks/sentinel.py +21 -17
- coredis/response/_callbacks/server.py +36 -14
- coredis/response/_callbacks/sets.py +3 -4
- coredis/response/_callbacks/sorted_set.py +27 -24
- coredis/response/_callbacks/streams.py +22 -13
- coredis/response/_callbacks/strings.py +7 -6
- coredis/response/_callbacks/vector_sets.py +126 -0
- coredis/response/types.py +13 -4
- coredis/sentinel.py +1 -1
- coredis/stream.py +4 -3
- coredis/tokens.py +343 -16
- coredis/typing.py +432 -79
- {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/METADATA +4 -5
- coredis-5.0.0rc1.dist-info/RECORD +95 -0
- coredis/client/keydb.py +0 -336
- coredis/pipeline.pyi +0 -2103
- coredis-4.23.1.dist-info/RECORD +0 -93
- {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/WHEEL +0 -0
- {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {coredis-4.23.1.dist-info → coredis-5.0.0rc1.dist-info}/top_level.txt +0 -0
coredis/client/basic.py
CHANGED
|
@@ -4,6 +4,7 @@ import asyncio
|
|
|
4
4
|
import contextlib
|
|
5
5
|
import contextvars
|
|
6
6
|
import functools
|
|
7
|
+
import random
|
|
7
8
|
import warnings
|
|
8
9
|
from collections import defaultdict
|
|
9
10
|
from ssl import SSLContext
|
|
@@ -14,7 +15,8 @@ from packaging import version
|
|
|
14
15
|
from packaging.version import InvalidVersion, Version
|
|
15
16
|
|
|
16
17
|
from coredis._utils import EncodingInsensitiveDict, nativestr
|
|
17
|
-
from coredis.cache import AbstractCache
|
|
18
|
+
from coredis.cache import AbstractCache
|
|
19
|
+
from coredis.commands import CommandRequest
|
|
18
20
|
from coredis.commands._key_spec import KeySpec
|
|
19
21
|
from coredis.commands.constants import CommandFlag, CommandName
|
|
20
22
|
from coredis.commands.core import CoreCommands
|
|
@@ -31,6 +33,7 @@ from coredis.connection import (
|
|
|
31
33
|
)
|
|
32
34
|
from coredis.credentials import AbstractCredentialProvider
|
|
33
35
|
from coredis.exceptions import (
|
|
36
|
+
AuthenticationError,
|
|
34
37
|
ConnectionError,
|
|
35
38
|
PersistenceError,
|
|
36
39
|
RedisError,
|
|
@@ -39,7 +42,7 @@ from coredis.exceptions import (
|
|
|
39
42
|
UnknownCommandError,
|
|
40
43
|
WatchError,
|
|
41
44
|
)
|
|
42
|
-
from coredis.globals import COMMAND_FLAGS, READONLY_COMMANDS
|
|
45
|
+
from coredis.globals import CACHEABLE_COMMANDS, COMMAND_FLAGS, READONLY_COMMANDS
|
|
43
46
|
from coredis.modules import ModuleMixin
|
|
44
47
|
from coredis.pool import ConnectionPool
|
|
45
48
|
from coredis.response._callbacks import (
|
|
@@ -55,6 +58,7 @@ from coredis.typing import (
|
|
|
55
58
|
AsyncIterator,
|
|
56
59
|
Callable,
|
|
57
60
|
Coroutine,
|
|
61
|
+
ExecutionParameters,
|
|
58
62
|
Generator,
|
|
59
63
|
Generic,
|
|
60
64
|
Iterator,
|
|
@@ -63,9 +67,14 @@ from coredis.typing import (
|
|
|
63
67
|
Mapping,
|
|
64
68
|
Parameters,
|
|
65
69
|
ParamSpec,
|
|
70
|
+
RedisCommandP,
|
|
71
|
+
RedisValueT,
|
|
66
72
|
ResponseType,
|
|
67
73
|
StringT,
|
|
74
|
+
T_co,
|
|
75
|
+
TypeAdapter,
|
|
68
76
|
TypeVar,
|
|
77
|
+
Unpack,
|
|
69
78
|
ValueT,
|
|
70
79
|
)
|
|
71
80
|
|
|
@@ -75,7 +84,6 @@ R = TypeVar("R")
|
|
|
75
84
|
if TYPE_CHECKING:
|
|
76
85
|
import coredis.pipeline
|
|
77
86
|
|
|
78
|
-
|
|
79
87
|
ClientT = TypeVar("ClientT", bound="Client[Any]")
|
|
80
88
|
RedisT = TypeVar("RedisT", bound="Redis[Any]")
|
|
81
89
|
|
|
@@ -93,6 +101,7 @@ class Client(
|
|
|
93
101
|
protocol_version: Literal[2, 3]
|
|
94
102
|
server_version: Version | None
|
|
95
103
|
callback_storage: dict[type[ResponseCallback[Any, Any, Any]], dict[str, Any]]
|
|
104
|
+
type_adapter: TypeAdapter
|
|
96
105
|
|
|
97
106
|
def __init__(
|
|
98
107
|
self,
|
|
@@ -126,6 +135,7 @@ class Client(
|
|
|
126
135
|
retry_policy: RetryPolicy = NoRetryPolicy(),
|
|
127
136
|
noevict: bool = False,
|
|
128
137
|
notouch: bool = False,
|
|
138
|
+
type_adapter: TypeAdapter | None = None,
|
|
129
139
|
**kwargs: Any,
|
|
130
140
|
):
|
|
131
141
|
if not connection_pool:
|
|
@@ -198,6 +208,30 @@ class Client(
|
|
|
198
208
|
self.retry_policy = retry_policy
|
|
199
209
|
self._module_info: dict[str, version.Version] | None = None
|
|
200
210
|
self.callback_storage = defaultdict(dict)
|
|
211
|
+
self.type_adapter = type_adapter or TypeAdapter()
|
|
212
|
+
|
|
213
|
+
def create_request(
|
|
214
|
+
self,
|
|
215
|
+
name: bytes,
|
|
216
|
+
*arguments: ValueT,
|
|
217
|
+
callback: Callable[..., T_co],
|
|
218
|
+
execution_parameters: ExecutionParameters | None = None,
|
|
219
|
+
) -> CommandRequest[T_co]:
|
|
220
|
+
"""
|
|
221
|
+
Factory method to create a command request awaitable.
|
|
222
|
+
Subclasses of :class:`coredis.client.Client` can override this method
|
|
223
|
+
if custom behavior is required. See :class:`~coredis.commands.CommandRequest`
|
|
224
|
+
for details.
|
|
225
|
+
|
|
226
|
+
:param name: The name of the command
|
|
227
|
+
:param arguments: all arguments sent to the command
|
|
228
|
+
:param callback: a callback that takes the RESP response and converts it
|
|
229
|
+
into a shape to be returned
|
|
230
|
+
:return: An instance of a command request bound to this client.
|
|
231
|
+
"""
|
|
232
|
+
return CommandRequest(
|
|
233
|
+
self, name, *arguments, callback=callback, execution_parameters=execution_parameters
|
|
234
|
+
)
|
|
201
235
|
|
|
202
236
|
@property
|
|
203
237
|
def noreply(self) -> bool:
|
|
@@ -220,9 +254,7 @@ class Client(
|
|
|
220
254
|
return False
|
|
221
255
|
return True
|
|
222
256
|
|
|
223
|
-
|
|
224
|
-
if self._module_info is None:
|
|
225
|
-
await self._populate_module_versions()
|
|
257
|
+
def get_server_module_version(self, module: str) -> version.Version | None:
|
|
226
258
|
return (self._module_info or {}).get(module)
|
|
227
259
|
|
|
228
260
|
def _ensure_server_version(self, version: str | None) -> None:
|
|
@@ -246,7 +278,7 @@ class Client(
|
|
|
246
278
|
self.server_version = None
|
|
247
279
|
|
|
248
280
|
async def _ensure_wait(
|
|
249
|
-
self, command:
|
|
281
|
+
self, command: RedisCommandP, connection: BaseConnection
|
|
250
282
|
) -> asyncio.Future[None]:
|
|
251
283
|
maybe_wait: asyncio.Future[None] = asyncio.get_running_loop().create_future()
|
|
252
284
|
wait = self._waitcontext.get()
|
|
@@ -257,7 +289,7 @@ class Client(
|
|
|
257
289
|
if exc:
|
|
258
290
|
maybe_wait.set_exception(exc)
|
|
259
291
|
elif not cast(int, response.result()) >= wait[0]:
|
|
260
|
-
maybe_wait.set_exception(ReplicationError(command, wait[0], wait[1]))
|
|
292
|
+
maybe_wait.set_exception(ReplicationError(command.name, wait[0], wait[1]))
|
|
261
293
|
else:
|
|
262
294
|
maybe_wait.set_result(None)
|
|
263
295
|
|
|
@@ -268,7 +300,7 @@ class Client(
|
|
|
268
300
|
return maybe_wait
|
|
269
301
|
|
|
270
302
|
async def _ensure_persistence(
|
|
271
|
-
self, command:
|
|
303
|
+
self, command: RedisCommandP, connection: BaseConnection
|
|
272
304
|
) -> asyncio.Future[None]:
|
|
273
305
|
maybe_wait: asyncio.Future[None] = asyncio.get_running_loop().create_future()
|
|
274
306
|
waitaof = self._waitaof_context.get()
|
|
@@ -283,7 +315,7 @@ class Client(
|
|
|
283
315
|
else:
|
|
284
316
|
res = cast(tuple[int, int], response.result())
|
|
285
317
|
if not (res[0] >= waitaof[0] and res[1] >= waitaof[1]):
|
|
286
|
-
maybe_wait.set_exception(PersistenceError(command, *waitaof))
|
|
318
|
+
maybe_wait.set_exception(PersistenceError(command.name, *waitaof))
|
|
287
319
|
else:
|
|
288
320
|
maybe_wait.set_result(None)
|
|
289
321
|
|
|
@@ -294,7 +326,7 @@ class Client(
|
|
|
294
326
|
return maybe_wait
|
|
295
327
|
|
|
296
328
|
async def _populate_module_versions(self) -> None:
|
|
297
|
-
if self.noreply:
|
|
329
|
+
if self.noreply or getattr(self, "_module_info", None) is not None:
|
|
298
330
|
return
|
|
299
331
|
try:
|
|
300
332
|
modules = await self.module_list()
|
|
@@ -307,11 +339,12 @@ class Client(
|
|
|
307
339
|
ver, minor = divmod(ver, 100)
|
|
308
340
|
ver, major = divmod(ver, 100)
|
|
309
341
|
self._module_info[name] = version.Version(f"{major}.{minor}.{patch}")
|
|
310
|
-
except UnknownCommandError:
|
|
342
|
+
except (UnknownCommandError, AuthenticationError):
|
|
311
343
|
self._module_info = {}
|
|
312
344
|
|
|
313
345
|
async def initialize(self: ClientT) -> ClientT:
|
|
314
346
|
await self.connection_pool.initialize()
|
|
347
|
+
await self._populate_module_versions()
|
|
315
348
|
return self
|
|
316
349
|
|
|
317
350
|
def __await__(self: ClientT) -> Generator[Any, None, ClientT]:
|
|
@@ -422,7 +455,7 @@ class Client(
|
|
|
422
455
|
for item in data:
|
|
423
456
|
yield item
|
|
424
457
|
|
|
425
|
-
def register_script(self, script:
|
|
458
|
+
def register_script(self, script: RedisValueT) -> Script[AnyStr]:
|
|
426
459
|
"""
|
|
427
460
|
Registers a Lua :paramref:`script`
|
|
428
461
|
|
|
@@ -538,8 +571,8 @@ class Client(
|
|
|
538
571
|
finally:
|
|
539
572
|
self._waitaof_context.set(None)
|
|
540
573
|
|
|
541
|
-
def should_quick_release(self, command:
|
|
542
|
-
return CommandFlag.BLOCKING not in COMMAND_FLAGS[command]
|
|
574
|
+
def should_quick_release(self, command: RedisCommandP) -> bool:
|
|
575
|
+
return CommandFlag.BLOCKING not in COMMAND_FLAGS[command.name]
|
|
543
576
|
|
|
544
577
|
|
|
545
578
|
class Redis(Client[AnyStr]):
|
|
@@ -580,6 +613,7 @@ class Redis(Client[AnyStr]):
|
|
|
580
613
|
noevict: bool = ...,
|
|
581
614
|
notouch: bool = ...,
|
|
582
615
|
retry_policy: RetryPolicy = ...,
|
|
616
|
+
type_adapter: TypeAdapter | None = ...,
|
|
583
617
|
**kwargs: Any,
|
|
584
618
|
) -> None: ...
|
|
585
619
|
|
|
@@ -618,6 +652,7 @@ class Redis(Client[AnyStr]):
|
|
|
618
652
|
noevict: bool = ...,
|
|
619
653
|
notouch: bool = ...,
|
|
620
654
|
retry_policy: RetryPolicy = ...,
|
|
655
|
+
type_adapter: TypeAdapter | None = ...,
|
|
621
656
|
**kwargs: Any,
|
|
622
657
|
) -> None: ...
|
|
623
658
|
|
|
@@ -655,6 +690,7 @@ class Redis(Client[AnyStr]):
|
|
|
655
690
|
noevict: bool = False,
|
|
656
691
|
notouch: bool = False,
|
|
657
692
|
retry_policy: RetryPolicy = ConstantRetryPolicy((ConnectionError, TimeoutError), 2, 0.01),
|
|
693
|
+
type_adapter: TypeAdapter | None = None,
|
|
658
694
|
**kwargs: Any,
|
|
659
695
|
) -> None:
|
|
660
696
|
"""
|
|
@@ -775,6 +811,8 @@ class Redis(Client[AnyStr]):
|
|
|
775
811
|
:param notouch: Ensures that commands sent by the client will not alter the LRU/LFU of
|
|
776
812
|
the keys they access.
|
|
777
813
|
:param retry_policy: The retry policy to use when interacting with the redis server
|
|
814
|
+
:param type_adapter: The adapter to use for serializing / deserializing customs types
|
|
815
|
+
when interacting with redis commands.
|
|
778
816
|
|
|
779
817
|
"""
|
|
780
818
|
super().__init__(
|
|
@@ -796,7 +834,7 @@ class Redis(Client[AnyStr]):
|
|
|
796
834
|
ssl_keyfile=ssl_keyfile,
|
|
797
835
|
ssl_certfile=ssl_certfile,
|
|
798
836
|
ssl_cert_reqs=ssl_cert_reqs,
|
|
799
|
-
|
|
837
|
+
ssl_check_hostname=ssl_check_hostname,
|
|
800
838
|
ssl_ca_certs=ssl_ca_certs,
|
|
801
839
|
max_connections=max_connections,
|
|
802
840
|
max_idle_time=max_idle_time,
|
|
@@ -808,6 +846,7 @@ class Redis(Client[AnyStr]):
|
|
|
808
846
|
noevict=noevict,
|
|
809
847
|
notouch=notouch,
|
|
810
848
|
retry_policy=retry_policy,
|
|
849
|
+
type_adapter=type_adapter,
|
|
811
850
|
**kwargs,
|
|
812
851
|
)
|
|
813
852
|
self.cache = cache
|
|
@@ -867,6 +906,7 @@ class Redis(Client[AnyStr]):
|
|
|
867
906
|
noevict: bool = False,
|
|
868
907
|
notouch: bool = False,
|
|
869
908
|
retry_policy: RetryPolicy = ConstantRetryPolicy((ConnectionError, TimeoutError), 2, 0.01),
|
|
909
|
+
type_adapter: TypeAdapter | None = None,
|
|
870
910
|
cache: AbstractCache | None = None,
|
|
871
911
|
**kwargs: Any,
|
|
872
912
|
) -> RedisT:
|
|
@@ -892,6 +932,7 @@ class Redis(Client[AnyStr]):
|
|
|
892
932
|
verify_version=verify_version,
|
|
893
933
|
noreply=noreply,
|
|
894
934
|
retry_policy=retry_policy,
|
|
935
|
+
type_adapter=type_adapter,
|
|
895
936
|
cache=cache,
|
|
896
937
|
connection_pool=ConnectionPool.from_url(
|
|
897
938
|
url,
|
|
@@ -911,6 +952,7 @@ class Redis(Client[AnyStr]):
|
|
|
911
952
|
verify_version=verify_version,
|
|
912
953
|
noreply=noreply,
|
|
913
954
|
retry_policy=retry_policy,
|
|
955
|
+
type_adapter=type_adapter,
|
|
914
956
|
cache=cache,
|
|
915
957
|
connection_pool=ConnectionPool.from_url(
|
|
916
958
|
url,
|
|
@@ -933,66 +975,97 @@ class Redis(Client[AnyStr]):
|
|
|
933
975
|
|
|
934
976
|
async def execute_command(
|
|
935
977
|
self,
|
|
936
|
-
command:
|
|
937
|
-
*args: ValueT,
|
|
978
|
+
command: RedisCommandP,
|
|
938
979
|
callback: Callable[..., R] = NoopCallback(),
|
|
939
|
-
**options:
|
|
980
|
+
**options: Unpack[ExecutionParameters],
|
|
940
981
|
) -> R:
|
|
941
982
|
"""
|
|
942
983
|
Executes a command with configured retries and returns
|
|
943
984
|
the parsed response
|
|
944
985
|
"""
|
|
945
986
|
return await self.retry_policy.call_with_retries(
|
|
946
|
-
lambda: self._execute_command(command,
|
|
987
|
+
lambda: self._execute_command(command, callback=callback, **options),
|
|
947
988
|
before_hook=self.initialize,
|
|
948
989
|
)
|
|
949
990
|
|
|
950
991
|
async def _execute_command(
|
|
951
992
|
self,
|
|
952
|
-
command:
|
|
953
|
-
*args: ValueT,
|
|
993
|
+
command: RedisCommandP,
|
|
954
994
|
callback: Callable[..., R] = NoopCallback(),
|
|
955
|
-
**options:
|
|
995
|
+
**options: Unpack[ExecutionParameters],
|
|
956
996
|
) -> R:
|
|
957
997
|
pool = self.connection_pool
|
|
958
998
|
quick_release = self.should_quick_release(command)
|
|
959
999
|
connection = await pool.get_connection(
|
|
960
|
-
command,
|
|
961
|
-
*
|
|
1000
|
+
command.name,
|
|
1001
|
+
*command.arguments,
|
|
962
1002
|
acquire=not quick_release or self.requires_wait or self.requires_waitaof,
|
|
963
1003
|
)
|
|
964
|
-
if (
|
|
965
|
-
self.cache
|
|
966
|
-
and isinstance(self.cache, SupportsClientTracking)
|
|
967
|
-
and connection.tracking_client_id != self.cache.get_client_id(connection)
|
|
968
|
-
):
|
|
969
|
-
self.cache.reset()
|
|
970
|
-
await connection.update_tracking_client(True, self.cache.get_client_id(connection))
|
|
971
1004
|
try:
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
decode=options.get("decode", self._decodecontext.get()),
|
|
979
|
-
encoding=self._encodingcontext.get(),
|
|
980
|
-
)
|
|
981
|
-
maybe_wait = [
|
|
982
|
-
await self._ensure_wait(command, connection),
|
|
983
|
-
await self._ensure_persistence(command, connection),
|
|
984
|
-
]
|
|
985
|
-
reply = await request
|
|
986
|
-
await asyncio.gather(*maybe_wait)
|
|
987
|
-
if self.noreply:
|
|
988
|
-
return None # type: ignore
|
|
989
|
-
if isinstance(callback, AsyncPreProcessingCallback):
|
|
990
|
-
await callback.pre_process(self, reply, version=self.protocol_version, **options)
|
|
991
|
-
return callback(
|
|
992
|
-
reply,
|
|
993
|
-
version=self.protocol_version,
|
|
994
|
-
**options,
|
|
1005
|
+
keys = KeySpec.extract_keys(command.name, *command.arguments)
|
|
1006
|
+
cacheable = (
|
|
1007
|
+
command.name in CACHEABLE_COMMANDS
|
|
1008
|
+
and len(keys) == 1
|
|
1009
|
+
and not self.noreply
|
|
1010
|
+
and self._decodecontext.get() is None
|
|
995
1011
|
)
|
|
1012
|
+
cached_reply = None
|
|
1013
|
+
cache_hit = False
|
|
1014
|
+
use_cached = False
|
|
1015
|
+
reply = None
|
|
1016
|
+
if self.cache:
|
|
1017
|
+
if connection.tracking_client_id != self.cache.get_client_id(connection):
|
|
1018
|
+
self.cache.reset()
|
|
1019
|
+
await connection.update_tracking_client(
|
|
1020
|
+
True, self.cache.get_client_id(connection)
|
|
1021
|
+
)
|
|
1022
|
+
if command.name not in READONLY_COMMANDS:
|
|
1023
|
+
self.cache.invalidate(*keys)
|
|
1024
|
+
elif cacheable:
|
|
1025
|
+
try:
|
|
1026
|
+
cached_reply = cast(
|
|
1027
|
+
R,
|
|
1028
|
+
self.cache.get(
|
|
1029
|
+
command.name,
|
|
1030
|
+
keys[0],
|
|
1031
|
+
*command.arguments,
|
|
1032
|
+
),
|
|
1033
|
+
)
|
|
1034
|
+
use_cached = random.random() * 100.0 < min(100.0, self.cache.confidence)
|
|
1035
|
+
cache_hit = True
|
|
1036
|
+
except KeyError:
|
|
1037
|
+
pass
|
|
1038
|
+
if not (use_cached and cached_reply):
|
|
1039
|
+
request = await connection.create_request(
|
|
1040
|
+
command.name,
|
|
1041
|
+
*command.arguments,
|
|
1042
|
+
noreply=self.noreply,
|
|
1043
|
+
decode=options.get("decode", self._decodecontext.get()),
|
|
1044
|
+
encoding=self._encodingcontext.get(),
|
|
1045
|
+
)
|
|
1046
|
+
maybe_wait = [
|
|
1047
|
+
await self._ensure_wait(command, connection),
|
|
1048
|
+
await self._ensure_persistence(command, connection),
|
|
1049
|
+
]
|
|
1050
|
+
reply = await request
|
|
1051
|
+
await asyncio.gather(*maybe_wait)
|
|
1052
|
+
if self.noreply:
|
|
1053
|
+
return None # type: ignore
|
|
1054
|
+
if isinstance(callback, AsyncPreProcessingCallback):
|
|
1055
|
+
await callback.pre_process(self, reply)
|
|
1056
|
+
if self.cache and cacheable:
|
|
1057
|
+
if cache_hit and not use_cached:
|
|
1058
|
+
self.cache.feedback(
|
|
1059
|
+
command.name, keys[0], *command.arguments, match=cached_reply == reply
|
|
1060
|
+
)
|
|
1061
|
+
if not cache_hit:
|
|
1062
|
+
self.cache.put(
|
|
1063
|
+
command.name,
|
|
1064
|
+
keys[0],
|
|
1065
|
+
*command.arguments,
|
|
1066
|
+
value=reply,
|
|
1067
|
+
)
|
|
1068
|
+
return callback(cached_reply if cache_hit else reply, version=self.protocol_version)
|
|
996
1069
|
except RedisError:
|
|
997
1070
|
connection.disconnect()
|
|
998
1071
|
raise
|
|
@@ -1121,7 +1194,7 @@ class Redis(Client[AnyStr]):
|
|
|
1121
1194
|
"""
|
|
1122
1195
|
from coredis.pipeline import Pipeline
|
|
1123
1196
|
|
|
1124
|
-
return Pipeline[AnyStr]
|
|
1197
|
+
return Pipeline[AnyStr](self, transaction, watches, timeout)
|
|
1125
1198
|
|
|
1126
1199
|
async def transaction(
|
|
1127
1200
|
self,
|