dycw-utilities 0.131.16__py3-none-any.whl → 0.131.17__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.
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.17.dist-info}/METADATA +1 -1
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.17.dist-info}/RECORD +12 -13
- utilities/__init__.py +1 -1
- utilities/asyncio.py +47 -60
- utilities/pottery.py +16 -19
- utilities/psutil.py +8 -7
- utilities/redis.py +108 -116
- utilities/slack_sdk.py +17 -18
- utilities/sqlalchemy.py +36 -30
- utilities/sqlalchemy_polars.py +12 -27
- utilities/tenacity.py +0 -145
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.17.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.131.16.dist-info → dycw_utilities-0.131.17.dist-info}/licenses/LICENSE +0 -0
utilities/redis.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
import asyncio
|
4
3
|
from asyncio import CancelledError, Event, Queue, Task, create_task
|
5
4
|
from collections.abc import AsyncIterator, Callable, Mapping
|
6
5
|
from contextlib import asynccontextmanager, suppress
|
@@ -24,18 +23,13 @@ from typing import (
|
|
24
23
|
|
25
24
|
from redis.asyncio import Redis
|
26
25
|
|
27
|
-
from utilities.asyncio import EnhancedQueue, Looper,
|
26
|
+
from utilities.asyncio import EnhancedQueue, Looper, sleep_td, timeout_td
|
28
27
|
from utilities.contextlib import suppress_super_object_attribute_error
|
29
|
-
from utilities.datetime import (
|
30
|
-
MILLISECOND,
|
31
|
-
SECOND,
|
32
|
-
datetime_duration_to_float,
|
33
|
-
datetime_duration_to_timedelta,
|
34
|
-
)
|
35
28
|
from utilities.errors import ImpossibleCaseError
|
36
29
|
from utilities.functions import ensure_int, identity
|
37
30
|
from utilities.iterables import always_iterable, one
|
38
31
|
from utilities.orjson import deserialize, serialize
|
32
|
+
from utilities.whenever2 import MILLISECOND, SECOND
|
39
33
|
|
40
34
|
if TYPE_CHECKING:
|
41
35
|
from collections.abc import (
|
@@ -51,9 +45,10 @@ if TYPE_CHECKING:
|
|
51
45
|
from redis.asyncio import ConnectionPool
|
52
46
|
from redis.asyncio.client import PubSub
|
53
47
|
from redis.typing import EncodableT, ResponseT
|
48
|
+
from whenever import TimeDelta
|
54
49
|
|
55
50
|
from utilities.iterables import MaybeIterable
|
56
|
-
from utilities.types import
|
51
|
+
from utilities.types import MaybeType, TypeLike
|
57
52
|
|
58
53
|
|
59
54
|
_K = TypeVar("_K")
|
@@ -72,7 +67,7 @@ _V2 = TypeVar("_V2")
|
|
72
67
|
_V3 = TypeVar("_V3")
|
73
68
|
|
74
69
|
|
75
|
-
_PUBLISH_TIMEOUT:
|
70
|
+
_PUBLISH_TIMEOUT: TimeDelta = SECOND
|
76
71
|
|
77
72
|
|
78
73
|
##
|
@@ -89,17 +84,17 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
89
84
|
value: TypeLike[_V]
|
90
85
|
value_serializer: Callable[[_V], bytes] | None = None
|
91
86
|
value_deserializer: Callable[[bytes], _V] | None = None
|
92
|
-
timeout:
|
87
|
+
timeout: TimeDelta | None = None
|
93
88
|
error: MaybeType[BaseException] = TimeoutError
|
94
|
-
ttl:
|
89
|
+
ttl: TimeDelta | None = None
|
95
90
|
|
96
91
|
async def delete(self, redis: Redis, key: _K, /) -> int:
|
97
92
|
"""Delete a key from a hashmap in `redis`."""
|
98
93
|
ser = _serialize( # skipif-ci-and-not-linux
|
99
94
|
key, serializer=self.key_serializer
|
100
95
|
).decode()
|
101
|
-
async with
|
102
|
-
|
96
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
97
|
+
self.timeout, error=self.error
|
103
98
|
):
|
104
99
|
return await cast("Awaitable[int]", redis.hdel(self.name, ser))
|
105
100
|
raise ImpossibleCaseError(case=[f"{redis=}", f"{key=}"]) # pragma: no cover
|
@@ -109,8 +104,8 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
109
104
|
ser = _serialize( # skipif-ci-and-not-linux
|
110
105
|
key, serializer=self.key_serializer
|
111
106
|
).decode()
|
112
|
-
async with
|
113
|
-
|
107
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
108
|
+
self.timeout, error=self.error
|
114
109
|
):
|
115
110
|
return await cast("Awaitable[bool]", redis.hexists(self.name, ser))
|
116
111
|
|
@@ -123,8 +118,8 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
123
118
|
|
124
119
|
async def get_all(self, redis: Redis, /) -> Mapping[_K, _V]:
|
125
120
|
"""Get a value from a hashmap in `redis`."""
|
126
|
-
async with
|
127
|
-
|
121
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
122
|
+
self.timeout, error=self.error
|
128
123
|
):
|
129
124
|
result = await cast( # skipif-ci-and-not-linux
|
130
125
|
"Awaitable[Mapping[bytes, bytes]]", redis.hgetall(self.name)
|
@@ -146,8 +141,8 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
146
141
|
ser = [ # skipif-ci-and-not-linux
|
147
142
|
_serialize(key, serializer=self.key_serializer) for key in keys
|
148
143
|
]
|
149
|
-
async with
|
150
|
-
|
144
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
145
|
+
self.timeout, error=self.error
|
151
146
|
):
|
152
147
|
result = await cast( # skipif-ci-and-not-linux
|
153
148
|
"Awaitable[Sequence[bytes | None]]", redis.hmget(self.name, ser)
|
@@ -161,8 +156,8 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
161
156
|
|
162
157
|
async def keys(self, redis: Redis, /) -> Sequence[_K]:
|
163
158
|
"""Get the keys of a hashmap in `redis`."""
|
164
|
-
async with
|
165
|
-
|
159
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
160
|
+
self.timeout, error=self.error
|
166
161
|
):
|
167
162
|
result = await cast("Awaitable[Sequence[bytes]]", redis.hkeys(self.name))
|
168
163
|
return [ # skipif-ci-and-not-linux
|
@@ -171,8 +166,8 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
171
166
|
|
172
167
|
async def length(self, redis: Redis, /) -> int:
|
173
168
|
"""Get the length of a hashmap in `redis`."""
|
174
|
-
async with
|
175
|
-
|
169
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
170
|
+
self.timeout, error=self.error
|
176
171
|
):
|
177
172
|
return await cast("Awaitable[int]", redis.hlen(self.name))
|
178
173
|
|
@@ -190,20 +185,20 @@ class RedisHashMapKey(Generic[_K, _V]):
|
|
190
185
|
)
|
191
186
|
for key, value in mapping.items()
|
192
187
|
}
|
193
|
-
async with
|
194
|
-
|
188
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
189
|
+
self.timeout, error=self.error
|
195
190
|
):
|
196
191
|
result = await cast(
|
197
192
|
"Awaitable[int]", redis.hset(self.name, mapping=cast("Any", ser))
|
198
193
|
)
|
199
194
|
if self.ttl is not None:
|
200
|
-
await redis.pexpire(self.name,
|
195
|
+
await redis.pexpire(self.name, self.ttl.py_timedelta())
|
201
196
|
return result # skipif-ci-and-not-linux
|
202
197
|
|
203
198
|
async def values(self, redis: Redis, /) -> Sequence[_V]:
|
204
199
|
"""Get the values of a hashmap in `redis`."""
|
205
|
-
async with
|
206
|
-
|
200
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
201
|
+
self.timeout, error=self.error
|
207
202
|
):
|
208
203
|
result = await cast("Awaitable[Sequence[bytes]]", redis.hvals(self.name))
|
209
204
|
return [ # skipif-ci-and-not-linux
|
@@ -222,9 +217,9 @@ def redis_hash_map_key(
|
|
222
217
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
223
218
|
value_serializer: Callable[[_V], bytes] | None = None,
|
224
219
|
value_deserializer: Callable[[bytes], _V] | None = None,
|
225
|
-
timeout:
|
220
|
+
timeout: TimeDelta | None = None,
|
226
221
|
error: type[Exception] = TimeoutError,
|
227
|
-
ttl:
|
222
|
+
ttl: TimeDelta | None = None,
|
228
223
|
) -> RedisHashMapKey[_K, _V]: ...
|
229
224
|
@overload
|
230
225
|
def redis_hash_map_key(
|
@@ -237,9 +232,9 @@ def redis_hash_map_key(
|
|
237
232
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
238
233
|
value_serializer: Callable[[_V1 | _V2], bytes] | None = None,
|
239
234
|
value_deserializer: Callable[[bytes], _V1 | _V2] | None = None,
|
240
|
-
timeout:
|
235
|
+
timeout: TimeDelta | None = None,
|
241
236
|
error: type[Exception] = TimeoutError,
|
242
|
-
ttl:
|
237
|
+
ttl: TimeDelta | None = None,
|
243
238
|
) -> RedisHashMapKey[_K, _V1 | _V2]: ...
|
244
239
|
@overload
|
245
240
|
def redis_hash_map_key(
|
@@ -252,9 +247,9 @@ def redis_hash_map_key(
|
|
252
247
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
253
248
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
254
249
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
255
|
-
timeout:
|
250
|
+
timeout: TimeDelta | None = None,
|
256
251
|
error: type[Exception] = TimeoutError,
|
257
|
-
ttl:
|
252
|
+
ttl: TimeDelta | None = None,
|
258
253
|
) -> RedisHashMapKey[_K, _V1 | _V2 | _V3]: ...
|
259
254
|
@overload
|
260
255
|
def redis_hash_map_key(
|
@@ -267,9 +262,9 @@ def redis_hash_map_key(
|
|
267
262
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
268
263
|
value_serializer: Callable[[_V], bytes] | None = None,
|
269
264
|
value_deserializer: Callable[[bytes], _V] | None = None,
|
270
|
-
timeout:
|
265
|
+
timeout: TimeDelta | None = None,
|
271
266
|
error: type[Exception] = TimeoutError,
|
272
|
-
ttl:
|
267
|
+
ttl: TimeDelta | None = None,
|
273
268
|
) -> RedisHashMapKey[_K1 | _K2, _V]: ...
|
274
269
|
@overload
|
275
270
|
def redis_hash_map_key(
|
@@ -282,9 +277,9 @@ def redis_hash_map_key(
|
|
282
277
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
283
278
|
value_serializer: Callable[[_V1 | _V2], bytes] | None = None,
|
284
279
|
value_deserializer: Callable[[bytes], _V1 | _V2] | None = None,
|
285
|
-
timeout:
|
280
|
+
timeout: TimeDelta | None = None,
|
286
281
|
error: type[Exception] = TimeoutError,
|
287
|
-
ttl:
|
282
|
+
ttl: TimeDelta | None = None,
|
288
283
|
) -> RedisHashMapKey[_K1 | _K2, _V1 | _V2]: ...
|
289
284
|
@overload
|
290
285
|
def redis_hash_map_key(
|
@@ -297,9 +292,9 @@ def redis_hash_map_key(
|
|
297
292
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
298
293
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
299
294
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
300
|
-
timeout:
|
295
|
+
timeout: TimeDelta | None = None,
|
301
296
|
error: type[Exception] = TimeoutError,
|
302
|
-
ttl:
|
297
|
+
ttl: TimeDelta | None = None,
|
303
298
|
) -> RedisHashMapKey[_K1 | _K2, _V1 | _V2 | _V3]: ...
|
304
299
|
@overload
|
305
300
|
def redis_hash_map_key(
|
@@ -312,9 +307,9 @@ def redis_hash_map_key(
|
|
312
307
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
313
308
|
value_serializer: Callable[[_V], bytes] | None = None,
|
314
309
|
value_deserializer: Callable[[bytes], _V] | None = None,
|
315
|
-
timeout:
|
310
|
+
timeout: TimeDelta | None = None,
|
316
311
|
error: type[Exception] = TimeoutError,
|
317
|
-
ttl:
|
312
|
+
ttl: TimeDelta | None = None,
|
318
313
|
) -> RedisHashMapKey[_K1 | _K2 | _K3, _V]: ...
|
319
314
|
@overload
|
320
315
|
def redis_hash_map_key(
|
@@ -327,9 +322,9 @@ def redis_hash_map_key(
|
|
327
322
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
328
323
|
value_serializer: Callable[[_V1 | _V2], bytes] | None = None,
|
329
324
|
value_deserializer: Callable[[bytes], _V1 | _V2] | None = None,
|
330
|
-
timeout:
|
325
|
+
timeout: TimeDelta | None = None,
|
331
326
|
error: type[Exception] = TimeoutError,
|
332
|
-
ttl:
|
327
|
+
ttl: TimeDelta | None = None,
|
333
328
|
) -> RedisHashMapKey[_K1 | _K2 | _K3, _V1 | _V2]: ...
|
334
329
|
@overload
|
335
330
|
def redis_hash_map_key(
|
@@ -342,9 +337,9 @@ def redis_hash_map_key(
|
|
342
337
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
343
338
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
344
339
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
345
|
-
timeout:
|
340
|
+
timeout: TimeDelta | None = None,
|
346
341
|
error: type[Exception] = TimeoutError,
|
347
|
-
ttl:
|
342
|
+
ttl: TimeDelta | None = None,
|
348
343
|
) -> RedisHashMapKey[_K1 | _K2 | _K3, _V1 | _V2 | _V3]: ...
|
349
344
|
@overload
|
350
345
|
def redis_hash_map_key(
|
@@ -357,9 +352,9 @@ def redis_hash_map_key(
|
|
357
352
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
358
353
|
value_serializer: Callable[[_V1 | _V2 | _V3], bytes] | None = None,
|
359
354
|
value_deserializer: Callable[[bytes], _V1 | _V2 | _V3] | None = None,
|
360
|
-
timeout:
|
355
|
+
timeout: TimeDelta | None = None,
|
361
356
|
error: type[Exception] = TimeoutError,
|
362
|
-
ttl:
|
357
|
+
ttl: TimeDelta | None = None,
|
363
358
|
) -> RedisHashMapKey[_K, _V]: ...
|
364
359
|
def redis_hash_map_key(
|
365
360
|
name: str,
|
@@ -371,8 +366,8 @@ def redis_hash_map_key(
|
|
371
366
|
key_deserializer: Callable[[bytes], Any] | None = None,
|
372
367
|
value_serializer: Callable[[Any], bytes] | None = None,
|
373
368
|
value_deserializer: Callable[[bytes], Any] | None = None,
|
374
|
-
timeout:
|
375
|
-
ttl:
|
369
|
+
timeout: TimeDelta | None = None,
|
370
|
+
ttl: TimeDelta | None = None,
|
376
371
|
error: type[Exception] = TimeoutError,
|
377
372
|
) -> RedisHashMapKey[_K, _V]:
|
378
373
|
"""Create a redis key."""
|
@@ -401,21 +396,21 @@ class RedisKey(Generic[_T]):
|
|
401
396
|
type: TypeLike[_T]
|
402
397
|
serializer: Callable[[_T], bytes] | None = None
|
403
398
|
deserializer: Callable[[bytes], _T] | None = None
|
404
|
-
timeout:
|
399
|
+
timeout: TimeDelta | None = None
|
405
400
|
error: MaybeType[BaseException] = TimeoutError
|
406
|
-
ttl:
|
401
|
+
ttl: TimeDelta | None = None
|
407
402
|
|
408
403
|
async def delete(self, redis: Redis, /) -> int:
|
409
404
|
"""Delete the key from `redis`."""
|
410
|
-
async with
|
411
|
-
|
405
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
406
|
+
self.timeout, error=self.error
|
412
407
|
):
|
413
408
|
return ensure_int(await redis.delete(self.name))
|
414
409
|
|
415
410
|
async def exists(self, redis: Redis, /) -> bool:
|
416
411
|
"""Check if the key exists in `redis`."""
|
417
|
-
async with
|
418
|
-
|
412
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
413
|
+
self.timeout, error=self.error
|
419
414
|
):
|
420
415
|
result = cast("Literal[0, 1]", await redis.exists(self.name))
|
421
416
|
match result: # skipif-ci-and-not-linux
|
@@ -426,8 +421,8 @@ class RedisKey(Generic[_T]):
|
|
426
421
|
|
427
422
|
async def get(self, redis: Redis, /) -> _T:
|
428
423
|
"""Get a value from `redis`."""
|
429
|
-
async with
|
430
|
-
|
424
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
425
|
+
self.timeout, error=self.error
|
431
426
|
):
|
432
427
|
result = cast("bytes | None", await redis.get(self.name))
|
433
428
|
if result is None: # skipif-ci-and-not-linux
|
@@ -440,12 +435,10 @@ class RedisKey(Generic[_T]):
|
|
440
435
|
"""Set a value in `redis`."""
|
441
436
|
ser = _serialize(value, serializer=self.serializer) # skipif-ci-and-not-linux
|
442
437
|
ttl = ( # skipif-ci-and-not-linux
|
443
|
-
None
|
444
|
-
if self.ttl is None
|
445
|
-
else round(1000 * datetime_duration_to_float(self.ttl))
|
438
|
+
None if self.ttl is None else round(self.ttl.in_milliseconds())
|
446
439
|
)
|
447
|
-
async with
|
448
|
-
|
440
|
+
async with timeout_td( # skipif-ci-and-not-linux
|
441
|
+
self.timeout, error=self.error
|
449
442
|
):
|
450
443
|
result = await redis.set( # skipif-ci-and-not-linux
|
451
444
|
self.name, ser, px=ttl
|
@@ -461,9 +454,9 @@ def redis_key(
|
|
461
454
|
*,
|
462
455
|
serializer: Callable[[_T], bytes] | None = None,
|
463
456
|
deserializer: Callable[[bytes], _T] | None = None,
|
464
|
-
timeout:
|
457
|
+
timeout: TimeDelta | None = None,
|
465
458
|
error: type[Exception] = TimeoutError,
|
466
|
-
ttl:
|
459
|
+
ttl: TimeDelta | None = None,
|
467
460
|
) -> RedisKey[_T]: ...
|
468
461
|
@overload
|
469
462
|
def redis_key(
|
@@ -473,9 +466,9 @@ def redis_key(
|
|
473
466
|
*,
|
474
467
|
serializer: Callable[[_T1 | _T2], bytes] | None = None,
|
475
468
|
deserializer: Callable[[bytes], _T1 | _T2] | None = None,
|
476
|
-
timeout:
|
469
|
+
timeout: TimeDelta | None = None,
|
477
470
|
error: type[Exception] = TimeoutError,
|
478
|
-
ttl:
|
471
|
+
ttl: TimeDelta | None = None,
|
479
472
|
) -> RedisKey[_T1 | _T2]: ...
|
480
473
|
@overload
|
481
474
|
def redis_key(
|
@@ -485,9 +478,9 @@ def redis_key(
|
|
485
478
|
*,
|
486
479
|
serializer: Callable[[_T1 | _T2 | _T3], bytes] | None = None,
|
487
480
|
deserializer: Callable[[bytes], _T1 | _T2 | _T3] | None = None,
|
488
|
-
timeout:
|
481
|
+
timeout: TimeDelta | None = None,
|
489
482
|
error: type[Exception] = TimeoutError,
|
490
|
-
ttl:
|
483
|
+
ttl: TimeDelta | None = None,
|
491
484
|
) -> RedisKey[_T1 | _T2 | _T3]: ...
|
492
485
|
@overload
|
493
486
|
def redis_key(
|
@@ -497,9 +490,9 @@ def redis_key(
|
|
497
490
|
*,
|
498
491
|
serializer: Callable[[_T1 | _T2 | _T3 | _T4], bytes] | None = None,
|
499
492
|
deserializer: Callable[[bytes], _T1 | _T2 | _T3 | _T4] | None = None,
|
500
|
-
timeout:
|
493
|
+
timeout: TimeDelta | None = None,
|
501
494
|
error: type[Exception] = TimeoutError,
|
502
|
-
ttl:
|
495
|
+
ttl: TimeDelta | None = None,
|
503
496
|
) -> RedisKey[_T1 | _T2 | _T3 | _T4]: ...
|
504
497
|
@overload
|
505
498
|
def redis_key(
|
@@ -509,9 +502,9 @@ def redis_key(
|
|
509
502
|
*,
|
510
503
|
serializer: Callable[[_T1 | _T2 | _T3 | _T4 | _T5], bytes] | None = None,
|
511
504
|
deserializer: Callable[[bytes], _T1 | _T2 | _T3 | _T4 | _T5] | None = None,
|
512
|
-
timeout:
|
505
|
+
timeout: TimeDelta | None = None,
|
513
506
|
error: type[Exception] = TimeoutError,
|
514
|
-
ttl:
|
507
|
+
ttl: TimeDelta | None = None,
|
515
508
|
) -> RedisKey[_T1 | _T2 | _T3 | _T4 | _T5]: ...
|
516
509
|
@overload
|
517
510
|
def redis_key(
|
@@ -521,9 +514,9 @@ def redis_key(
|
|
521
514
|
*,
|
522
515
|
serializer: Callable[[_T1 | _T2 | _T3 | _T4 | _T5], bytes] | None = None,
|
523
516
|
deserializer: Callable[[bytes], _T1 | _T2 | _T3 | _T4 | _T5] | None = None,
|
524
|
-
timeout:
|
517
|
+
timeout: TimeDelta | None = None,
|
525
518
|
error: type[Exception] = TimeoutError,
|
526
|
-
ttl:
|
519
|
+
ttl: TimeDelta | None = None,
|
527
520
|
) -> RedisKey[_T]: ...
|
528
521
|
def redis_key(
|
529
522
|
name: str,
|
@@ -532,9 +525,9 @@ def redis_key(
|
|
532
525
|
*,
|
533
526
|
serializer: Callable[[Any], bytes] | None = None,
|
534
527
|
deserializer: Callable[[bytes], Any] | None = None,
|
535
|
-
timeout:
|
528
|
+
timeout: TimeDelta | None = None,
|
536
529
|
error: type[Exception] = TimeoutError,
|
537
|
-
ttl:
|
530
|
+
ttl: TimeDelta | None = None,
|
538
531
|
) -> RedisKey[_T]:
|
539
532
|
"""Create a redis key."""
|
540
533
|
return RedisKey( # skipif-ci-and-not-linux
|
@@ -559,7 +552,7 @@ async def publish(
|
|
559
552
|
/,
|
560
553
|
*,
|
561
554
|
serializer: Callable[[_T], EncodableT],
|
562
|
-
timeout:
|
555
|
+
timeout: TimeDelta = _PUBLISH_TIMEOUT,
|
563
556
|
) -> ResponseT: ...
|
564
557
|
@overload
|
565
558
|
async def publish(
|
@@ -569,7 +562,7 @@ async def publish(
|
|
569
562
|
/,
|
570
563
|
*,
|
571
564
|
serializer: None = None,
|
572
|
-
timeout:
|
565
|
+
timeout: TimeDelta = _PUBLISH_TIMEOUT,
|
573
566
|
) -> ResponseT: ...
|
574
567
|
@overload
|
575
568
|
async def publish(
|
@@ -579,7 +572,7 @@ async def publish(
|
|
579
572
|
/,
|
580
573
|
*,
|
581
574
|
serializer: Callable[[_T], EncodableT] | None = None,
|
582
|
-
timeout:
|
575
|
+
timeout: TimeDelta = _PUBLISH_TIMEOUT,
|
583
576
|
) -> ResponseT: ...
|
584
577
|
async def publish(
|
585
578
|
redis: Redis,
|
@@ -588,7 +581,7 @@ async def publish(
|
|
588
581
|
/,
|
589
582
|
*,
|
590
583
|
serializer: Callable[[_T], EncodableT] | None = None,
|
591
|
-
timeout:
|
584
|
+
timeout: TimeDelta = _PUBLISH_TIMEOUT,
|
592
585
|
) -> ResponseT:
|
593
586
|
"""Publish an object to a channel."""
|
594
587
|
match data, serializer: # skipif-ci-and-not-linux
|
@@ -600,7 +593,7 @@ async def publish(
|
|
600
593
|
data_use = serializer(data)
|
601
594
|
case _ as never:
|
602
595
|
assert_never(never)
|
603
|
-
async with
|
596
|
+
async with timeout_td(timeout): # skipif-ci-and-not-linux
|
604
597
|
return await redis.publish(channel, data_use) # skipif-ci-and-not-linux
|
605
598
|
|
606
599
|
|
@@ -624,13 +617,13 @@ class PublishService(Looper[tuple[str, _T]]):
|
|
624
617
|
"""Service to publish items to Redis."""
|
625
618
|
|
626
619
|
# base
|
627
|
-
freq:
|
628
|
-
backoff:
|
620
|
+
freq: TimeDelta = field(default=MILLISECOND, repr=False)
|
621
|
+
backoff: TimeDelta = field(default=SECOND, repr=False)
|
629
622
|
empty_upon_exit: bool = field(default=True, repr=False)
|
630
623
|
# self
|
631
624
|
redis: Redis
|
632
625
|
serializer: Callable[[_T], EncodableT] = serialize
|
633
|
-
publish_timeout:
|
626
|
+
publish_timeout: TimeDelta = _PUBLISH_TIMEOUT
|
634
627
|
|
635
628
|
@override
|
636
629
|
async def core(self) -> None:
|
@@ -654,17 +647,17 @@ class PublishServiceMixin(Generic[_T]):
|
|
654
647
|
"""Mix-in for the publish service."""
|
655
648
|
|
656
649
|
# base - looper
|
657
|
-
publish_service_freq:
|
658
|
-
publish_service_backoff:
|
650
|
+
publish_service_freq: TimeDelta = field(default=MILLISECOND, repr=False)
|
651
|
+
publish_service_backoff: TimeDelta = field(default=SECOND, repr=False)
|
659
652
|
publish_service_empty_upon_exit: bool = field(default=False, repr=False)
|
660
653
|
publish_service_logger: str | None = field(default=None, repr=False)
|
661
|
-
publish_service_timeout:
|
654
|
+
publish_service_timeout: TimeDelta | None = field(default=None, repr=False)
|
662
655
|
publish_service_debug: bool = field(default=False, repr=False)
|
663
656
|
_is_pending_restart: Event = field(default_factory=Event, init=False, repr=False)
|
664
657
|
# base - publish service
|
665
658
|
publish_service_redis: Redis
|
666
659
|
publish_service_serializer: Callable[[_T], EncodableT] = serialize
|
667
|
-
publish_service_publish_timeout:
|
660
|
+
publish_service_publish_timeout: TimeDelta = _PUBLISH_TIMEOUT
|
668
661
|
# self
|
669
662
|
_publish_service: PublishService[_T] = field(init=False, repr=False)
|
670
663
|
|
@@ -694,8 +687,8 @@ class PublishServiceMixin(Generic[_T]):
|
|
694
687
|
##
|
695
688
|
|
696
689
|
|
697
|
-
_SUBSCRIBE_TIMEOUT:
|
698
|
-
_SUBSCRIBE_SLEEP:
|
690
|
+
_SUBSCRIBE_TIMEOUT: TimeDelta = SECOND
|
691
|
+
_SUBSCRIBE_SLEEP: TimeDelta = MILLISECOND
|
699
692
|
|
700
693
|
|
701
694
|
@overload
|
@@ -706,8 +699,8 @@ def subscribe(
|
|
706
699
|
queue: Queue[_RedisMessage],
|
707
700
|
/,
|
708
701
|
*,
|
709
|
-
timeout:
|
710
|
-
sleep:
|
702
|
+
timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT,
|
703
|
+
sleep: TimeDelta = _SUBSCRIBE_SLEEP,
|
711
704
|
output: Literal["raw"],
|
712
705
|
filter_: Callable[[_RedisMessage], bool] | None = None,
|
713
706
|
) -> AsyncIterator[Task[None]]: ...
|
@@ -719,8 +712,8 @@ def subscribe(
|
|
719
712
|
queue: Queue[bytes],
|
720
713
|
/,
|
721
714
|
*,
|
722
|
-
timeout:
|
723
|
-
sleep:
|
715
|
+
timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT,
|
716
|
+
sleep: TimeDelta = _SUBSCRIBE_SLEEP,
|
724
717
|
output: Literal["bytes"],
|
725
718
|
filter_: Callable[[bytes], bool] | None = None,
|
726
719
|
) -> AsyncIterator[Task[None]]: ...
|
@@ -732,8 +725,8 @@ def subscribe(
|
|
732
725
|
queue: Queue[str],
|
733
726
|
/,
|
734
727
|
*,
|
735
|
-
timeout:
|
736
|
-
sleep:
|
728
|
+
timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT,
|
729
|
+
sleep: TimeDelta = _SUBSCRIBE_SLEEP,
|
737
730
|
output: Literal["text"] = "text",
|
738
731
|
filter_: Callable[[str], bool] | None = None,
|
739
732
|
) -> AsyncIterator[Task[None]]: ...
|
@@ -745,8 +738,8 @@ def subscribe(
|
|
745
738
|
queue: Queue[_T],
|
746
739
|
/,
|
747
740
|
*,
|
748
|
-
timeout:
|
749
|
-
sleep:
|
741
|
+
timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT,
|
742
|
+
sleep: TimeDelta = _SUBSCRIBE_SLEEP,
|
750
743
|
output: Callable[[bytes], _T],
|
751
744
|
filter_: Callable[[_T], bool] | None = None,
|
752
745
|
) -> AsyncIterator[Task[None]]: ...
|
@@ -757,8 +750,8 @@ async def subscribe(
|
|
757
750
|
queue: Queue[_RedisMessage] | Queue[bytes] | Queue[_T],
|
758
751
|
/,
|
759
752
|
*,
|
760
|
-
timeout:
|
761
|
-
sleep:
|
753
|
+
timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT,
|
754
|
+
sleep: TimeDelta = _SUBSCRIBE_SLEEP,
|
762
755
|
output: Literal["raw", "bytes", "text"] | Callable[[bytes], _T] = "text",
|
763
756
|
filter_: Callable[[Any], bool] | None = None,
|
764
757
|
) -> AsyncIterator[Task[None]]:
|
@@ -808,14 +801,13 @@ async def _subscribe_core(
|
|
808
801
|
queue: Queue[Any],
|
809
802
|
/,
|
810
803
|
*,
|
811
|
-
timeout:
|
812
|
-
sleep:
|
804
|
+
timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT,
|
805
|
+
sleep: TimeDelta = _SUBSCRIBE_SLEEP,
|
813
806
|
filter_: Callable[[Any], bool] | None = None,
|
814
807
|
) -> None:
|
815
808
|
timeout_use = ( # skipif-ci-and-not-linux
|
816
|
-
None if timeout is None else
|
809
|
+
None if timeout is None else timeout.in_seconds()
|
817
810
|
)
|
818
|
-
sleep_use = datetime_duration_to_float(sleep) # skipif-ci-and-not-linux
|
819
811
|
is_subscribe_message = partial( # skipif-ci-and-not-linux
|
820
812
|
_is_message, channels={c.encode() for c in channels}
|
821
813
|
)
|
@@ -830,7 +822,7 @@ async def _subscribe_core(
|
|
830
822
|
else:
|
831
823
|
queue.put_nowait(transformed)
|
832
824
|
else:
|
833
|
-
await
|
825
|
+
await sleep_td(sleep)
|
834
826
|
|
835
827
|
|
836
828
|
def _is_message(
|
@@ -864,15 +856,15 @@ class SubscribeService(Looper[_T]):
|
|
864
856
|
"""Service to subscribe to Redis."""
|
865
857
|
|
866
858
|
# base
|
867
|
-
freq:
|
868
|
-
backoff:
|
859
|
+
freq: TimeDelta = field(default=MILLISECOND, repr=False)
|
860
|
+
backoff: TimeDelta = field(default=SECOND, repr=False)
|
869
861
|
logger: str | None = field(default=__name__, repr=False)
|
870
862
|
# self
|
871
863
|
redis: Redis
|
872
864
|
channel: str
|
873
865
|
deserializer: Callable[[bytes], _T] = deserialize
|
874
|
-
subscribe_timeout:
|
875
|
-
subscribe_sleep:
|
866
|
+
subscribe_timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT
|
867
|
+
subscribe_sleep: TimeDelta = _SUBSCRIBE_SLEEP
|
876
868
|
filter_: Callable[[_T], bool] | None = None
|
877
869
|
_is_subscribed: Event = field(default_factory=Event, init=False, repr=False)
|
878
870
|
|
@@ -934,18 +926,18 @@ class SubscribeServiceMixin(Generic[_T]):
|
|
934
926
|
"""Mix-in for the subscribe service."""
|
935
927
|
|
936
928
|
# base - looper
|
937
|
-
subscribe_service_freq:
|
938
|
-
subscribe_service_backoff:
|
929
|
+
subscribe_service_freq: TimeDelta = field(default=MILLISECOND, repr=False)
|
930
|
+
subscribe_service_backoff: TimeDelta = field(default=SECOND, repr=False)
|
939
931
|
subscribe_service_empty_upon_exit: bool = field(default=False, repr=False)
|
940
932
|
subscribe_service_logger: str | None = field(default=None, repr=False)
|
941
|
-
subscribe_service_timeout:
|
933
|
+
subscribe_service_timeout: TimeDelta | None = field(default=None, repr=False)
|
942
934
|
subscribe_service_debug: bool = field(default=False, repr=False)
|
943
935
|
# base - looper
|
944
936
|
subscribe_service_redis: Redis
|
945
937
|
subscribe_service_channel: str
|
946
938
|
subscribe_service_deserializer: Callable[[bytes], _T] = deserialize
|
947
|
-
subscribe_service_subscribe_sleep:
|
948
|
-
subscribe_service_subscribe_timeout:
|
939
|
+
subscribe_service_subscribe_sleep: TimeDelta = _SUBSCRIBE_SLEEP
|
940
|
+
subscribe_service_subscribe_timeout: TimeDelta | None = _SUBSCRIBE_TIMEOUT
|
949
941
|
# self
|
950
942
|
_subscribe_service: SubscribeService[_T] = field(init=False, repr=False)
|
951
943
|
|