meta-memcache 2.3.0__tar.gz → 2.5.0__tar.gz
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.
- {meta_memcache-2.3.0/src/meta_memcache.egg-info → meta_memcache-2.5.0}/PKG-INFO +12 -1
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/README.md +11 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/pyproject.toml +6 -1
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/__init__.py +1 -1
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/commands/high_level_commands.py +82 -23
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/extras/probabilistic_hot_cache.py +56 -9
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/high_level_commands.py +7 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0/src/meta_memcache.egg-info}/PKG-INFO +12 -1
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/LICENSE +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/setup.cfg +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/base/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/base/base_cache_client.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/base/base_serializer.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/cache_client.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/commands/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/commands/meta_commands.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/compression/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/compression/zstd_manager.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/configuration.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/connection/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/connection/memcache_socket.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/connection/pool.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/connection/providers.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/errors.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/events/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/events/write_failure_event.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/executors/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/executors/default.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/extras/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/extras/client_wrapper.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/extras/migrating_cache_client.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/cache_api.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/commands.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/executor.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/meta_commands.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/router.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/metrics/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/metrics/base.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/metrics/prometheus.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/protocol.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/py.typed +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/routers/__init__.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/routers/default.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/routers/ephemeral.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/routers/gutter.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/routers/helpers.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/serializer.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/settings.py +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache.egg-info/SOURCES.txt +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache.egg-info/dependency_links.txt +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache.egg-info/requires.txt +0 -0
- {meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-memcache
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Modern, pure python, memcache client with support for new meta commands.
|
|
5
5
|
Author-email: Guillermo Perez <bisho@revenuecat.com>
|
|
6
6
|
License: MIT License
|
|
@@ -434,6 +434,17 @@ Invalidation...
|
|
|
434
434
|
Get multiple keys at once
|
|
435
435
|
"""
|
|
436
436
|
|
|
437
|
+
def multi_get_cas(
|
|
438
|
+
self,
|
|
439
|
+
keys: List[Union[Key, str]],
|
|
440
|
+
touch_ttl: Optional[int] = None,
|
|
441
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
442
|
+
) -> Dict[Key, Tuple[Optional[Any], Optional[int]]]:
|
|
443
|
+
"""
|
|
444
|
+
Same as multi_get(), but also return the CAS tokens so
|
|
445
|
+
they can be used during writes and detect races
|
|
446
|
+
"""
|
|
447
|
+
|
|
437
448
|
def get_cas(
|
|
438
449
|
self,
|
|
439
450
|
key: Union[Key, str],
|
|
@@ -416,6 +416,17 @@ Invalidation...
|
|
|
416
416
|
Get multiple keys at once
|
|
417
417
|
"""
|
|
418
418
|
|
|
419
|
+
def multi_get_cas(
|
|
420
|
+
self,
|
|
421
|
+
keys: List[Union[Key, str]],
|
|
422
|
+
touch_ttl: Optional[int] = None,
|
|
423
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
424
|
+
) -> Dict[Key, Tuple[Optional[Any], Optional[int]]]:
|
|
425
|
+
"""
|
|
426
|
+
Same as multi_get(), but also return the CAS tokens so
|
|
427
|
+
they can be used during writes and detect races
|
|
428
|
+
"""
|
|
429
|
+
|
|
419
430
|
def get_cas(
|
|
420
431
|
self,
|
|
421
432
|
key: Union[Key, str],
|
|
@@ -8,7 +8,7 @@ dependencies = [
|
|
|
8
8
|
authors = [{ name = "Guillermo Perez", email = "bisho@revenuecat.com" }]
|
|
9
9
|
license = { text = "MIT License" }
|
|
10
10
|
name = "meta-memcache"
|
|
11
|
-
version = "2.
|
|
11
|
+
version = "2.5.0"
|
|
12
12
|
description = "Modern, pure python, memcache client with support for new meta commands."
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
requires-python = ">=3.10"
|
|
@@ -41,6 +41,11 @@ show_missing = true
|
|
|
41
41
|
[tool.ruff]
|
|
42
42
|
line-length = 88
|
|
43
43
|
|
|
44
|
+
[tool.ruff.lint]
|
|
45
|
+
# Ruff 0.16 expanded the default rule set from 59 to 413 rules. Pin the selection
|
|
46
|
+
# to the pre-0.16 default so version bumps don't silently add new rules.
|
|
47
|
+
select = ["E4", "E7", "E9", "F"]
|
|
48
|
+
|
|
44
49
|
[tool.ruff.lint.per-file-ignores]
|
|
45
50
|
"tests/*.py" = ["E731"]
|
|
46
51
|
"src/meta_memcache/__init__.py" = ["F401"]
|
{meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/commands/high_level_commands.py
RENAMED
|
@@ -18,6 +18,7 @@ from meta_memcache.interfaces.high_level_commands import HighLevelCommandsProtoc
|
|
|
18
18
|
from meta_memcache.interfaces.meta_commands import MetaCommandsProtocol
|
|
19
19
|
from meta_memcache.interfaces.router import FailureHandling
|
|
20
20
|
from meta_memcache.protocol import (
|
|
21
|
+
MA_MODE_DEC,
|
|
21
22
|
Key,
|
|
22
23
|
Miss,
|
|
23
24
|
ReadResponse,
|
|
@@ -25,7 +26,6 @@ from meta_memcache.protocol import (
|
|
|
25
26
|
SetMode,
|
|
26
27
|
Success,
|
|
27
28
|
Value,
|
|
28
|
-
MA_MODE_DEC,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
T = TypeVar("T")
|
|
@@ -59,6 +59,15 @@ class HighLevelCommandMixinWithMetaCommands(
|
|
|
59
59
|
return_cas_token: bool = False,
|
|
60
60
|
) -> Optional[Value]: ... # pragma: no cover
|
|
61
61
|
|
|
62
|
+
def _get_or_lease(
|
|
63
|
+
self,
|
|
64
|
+
key: Union[Key, str],
|
|
65
|
+
lease_policy: LeasePolicy,
|
|
66
|
+
touch_ttl: Optional[int] = None,
|
|
67
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
68
|
+
lease_wait_fn: Optional[Callable[[float], None]] = None,
|
|
69
|
+
) -> Optional[Value]: ... # pragma: no cover
|
|
70
|
+
|
|
62
71
|
def _process_get_result(
|
|
63
72
|
self, key: Union[Key, str], result: ReadResponse
|
|
64
73
|
) -> Optional[Value]: ... # pragma: no cover
|
|
@@ -249,14 +258,14 @@ class HighLevelCommandsMixin:
|
|
|
249
258
|
``lease_wait_fn`` is invoked with the number of seconds to wait
|
|
250
259
|
between lease retries. Defaults to ``time.sleep``.
|
|
251
260
|
"""
|
|
252
|
-
|
|
261
|
+
result = self._get_or_lease(
|
|
253
262
|
key=key,
|
|
254
263
|
lease_policy=lease_policy,
|
|
255
264
|
touch_ttl=touch_ttl,
|
|
256
265
|
recache_policy=recache_policy,
|
|
257
266
|
lease_wait_fn=lease_wait_fn,
|
|
258
267
|
)
|
|
259
|
-
return value
|
|
268
|
+
return result.value if result is not None else None
|
|
260
269
|
|
|
261
270
|
def get_or_lease_cas(
|
|
262
271
|
self: HighLevelCommandMixinWithMetaCommands,
|
|
@@ -270,6 +279,35 @@ class HighLevelCommandsMixin:
|
|
|
270
279
|
Same as get_or_lease(), but also return the CAS token so
|
|
271
280
|
it can be used during writes and detect races
|
|
272
281
|
"""
|
|
282
|
+
result = self._get_or_lease(
|
|
283
|
+
key=key,
|
|
284
|
+
lease_policy=lease_policy,
|
|
285
|
+
touch_ttl=touch_ttl,
|
|
286
|
+
recache_policy=recache_policy,
|
|
287
|
+
lease_wait_fn=lease_wait_fn,
|
|
288
|
+
)
|
|
289
|
+
if result is None:
|
|
290
|
+
return None, None
|
|
291
|
+
return result.value, result.flags.cas_token
|
|
292
|
+
|
|
293
|
+
def _get_or_lease(
|
|
294
|
+
self: HighLevelCommandMixinWithMetaCommands,
|
|
295
|
+
key: Union[Key, str],
|
|
296
|
+
lease_policy: LeasePolicy,
|
|
297
|
+
touch_ttl: Optional[int] = None,
|
|
298
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
299
|
+
lease_wait_fn: Optional[Callable[[float], None]] = None,
|
|
300
|
+
) -> Optional[Value]:
|
|
301
|
+
"""
|
|
302
|
+
Internal version of get_or_lease() that returns the raw Value, so
|
|
303
|
+
wrappers can inspect the response flags, i.e. to decide whether the
|
|
304
|
+
value is worth promoting into a local cache, or read the CAS token.
|
|
305
|
+
|
|
306
|
+
`Value.value` is None when the caller must behave as if this was a
|
|
307
|
+
miss: either it won the lease, or it lost and ran out of retries.
|
|
308
|
+
The Value itself is still returned in both cases, since the lease
|
|
309
|
+
winner needs its CAS token to write the value back.
|
|
310
|
+
"""
|
|
273
311
|
if lease_policy.miss_retries <= 0:
|
|
274
312
|
raise ValueError(
|
|
275
313
|
"Wrong lease_policy: miss_retries needs to be greater than 0"
|
|
@@ -295,30 +333,25 @@ class HighLevelCommandsMixin:
|
|
|
295
333
|
return_cas_token=True,
|
|
296
334
|
)
|
|
297
335
|
|
|
298
|
-
if isinstance(result, Value):
|
|
299
|
-
# It is a hit.
|
|
300
|
-
if result.flags.win:
|
|
301
|
-
# Win flag present, meaning we got the lease to
|
|
302
|
-
# recache/cache the item. We need to mimic a miss.
|
|
303
|
-
return None, result.flags.cas_token
|
|
304
|
-
if result.size == 0 and result.flags.win is False:
|
|
305
|
-
# The value is empty, this is a miss lease,
|
|
306
|
-
# and we lost, so we must keep retrying and
|
|
307
|
-
# wait for the.flags.winner to populate the value.
|
|
308
|
-
if i < lease_policy.miss_retries:
|
|
309
|
-
continue
|
|
310
|
-
else:
|
|
311
|
-
# We run out of retries, behave as a miss
|
|
312
|
-
return None, result.flags.cas_token
|
|
313
|
-
else:
|
|
314
|
-
# There is data, either the is no lease or
|
|
315
|
-
# we lost and should use the stale value.
|
|
316
|
-
return result.value, result.flags.cas_token
|
|
317
|
-
else:
|
|
336
|
+
if not isinstance(result, Value):
|
|
318
337
|
# With MISS_LEASE_TTL we should always get a value
|
|
319
338
|
# because on miss a lease empty value is generated
|
|
320
339
|
raise MemcacheError(f"Unexpected response: {result} for key {key}")
|
|
321
340
|
|
|
341
|
+
if (
|
|
342
|
+
result.size == 0
|
|
343
|
+
and result.flags.win is False
|
|
344
|
+
and i < lease_policy.miss_retries
|
|
345
|
+
):
|
|
346
|
+
# This is a miss lease and we lost, so we must keep retrying
|
|
347
|
+
# and wait for the winner to populate the value.
|
|
348
|
+
continue
|
|
349
|
+
|
|
350
|
+
# Either there is data, or we got a placeholder: we won the lease,
|
|
351
|
+
# or we lost and ran out of retries. _process_get_result() already
|
|
352
|
+
# cleared the value of the placeholders, so both behave as a miss.
|
|
353
|
+
return result
|
|
354
|
+
|
|
322
355
|
def get(
|
|
323
356
|
self: HighLevelCommandMixinWithMetaCommands,
|
|
324
357
|
key: Union[Key, str],
|
|
@@ -352,6 +385,27 @@ class HighLevelCommandsMixin:
|
|
|
352
385
|
)
|
|
353
386
|
return {k: v.value if v is not None else None for k, v in results.items()}
|
|
354
387
|
|
|
388
|
+
def multi_get_cas(
|
|
389
|
+
self: HighLevelCommandMixinWithMetaCommands,
|
|
390
|
+
keys: Iterable[Union[Key, str]],
|
|
391
|
+
touch_ttl: Optional[int] = None,
|
|
392
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
393
|
+
) -> Dict[Key, Tuple[Optional[Any], Optional[int]]]:
|
|
394
|
+
"""
|
|
395
|
+
Same as multi_get(), but also return the CAS tokens so
|
|
396
|
+
they can be used during writes and detect races
|
|
397
|
+
"""
|
|
398
|
+
results = self._multi_get(
|
|
399
|
+
keys=keys,
|
|
400
|
+
touch_ttl=touch_ttl,
|
|
401
|
+
recache_policy=recache_policy,
|
|
402
|
+
return_cas_token=True,
|
|
403
|
+
)
|
|
404
|
+
return {
|
|
405
|
+
k: (v.value, v.flags.cas_token) if v is not None else (None, None)
|
|
406
|
+
for k, v in results.items()
|
|
407
|
+
}
|
|
408
|
+
|
|
355
409
|
def _multi_get(
|
|
356
410
|
self: HighLevelCommandMixinWithMetaCommands,
|
|
357
411
|
keys: Iterable[Union[Key, str]],
|
|
@@ -423,6 +477,11 @@ class HighLevelCommandsMixin:
|
|
|
423
477
|
# recache the item. We need to mimic a miss, so
|
|
424
478
|
# we set the value to None.
|
|
425
479
|
result.value = None
|
|
480
|
+
elif result.size == 0 and result.flags.win is False:
|
|
481
|
+
# An empty value with a lose flag is the placeholder the
|
|
482
|
+
# server plants on a lease miss, while the winner
|
|
483
|
+
# repopulates it. There is no value to return either.
|
|
484
|
+
result.value = None
|
|
426
485
|
return result
|
|
427
486
|
elif isinstance(result, Miss):
|
|
428
487
|
return None
|
{meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/extras/probabilistic_hot_cache.py
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import pickle
|
|
1
2
|
import random
|
|
2
3
|
import threading
|
|
3
4
|
import time
|
|
4
5
|
from dataclasses import dataclass
|
|
5
|
-
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
|
|
6
|
-
import pickle
|
|
6
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
|
|
7
7
|
|
|
8
8
|
from marisa_trie import Trie # type: ignore
|
|
9
9
|
|
|
10
|
-
from meta_memcache.configuration import RecachePolicy
|
|
10
|
+
from meta_memcache.configuration import LeasePolicy, RecachePolicy
|
|
11
11
|
from meta_memcache.extras.client_wrapper import ClientWrapper
|
|
12
12
|
from meta_memcache.interfaces.cache_api import CacheApi
|
|
13
13
|
from meta_memcache.metrics.base import BaseMetricsCollector, MetricDefinition
|
|
@@ -191,6 +191,39 @@ class ProbabilisticHotCache(ClientWrapper):
|
|
|
191
191
|
key: Union[Key, str],
|
|
192
192
|
touch_ttl: Optional[int] = None,
|
|
193
193
|
recache_policy: Optional[RecachePolicy] = None,
|
|
194
|
+
) -> Optional[Any]:
|
|
195
|
+
return self._hot_cache_get(
|
|
196
|
+
key=key,
|
|
197
|
+
touch_ttl=touch_ttl,
|
|
198
|
+
recache_policy=recache_policy,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def get_or_lease(
|
|
202
|
+
self,
|
|
203
|
+
key: Union[Key, str],
|
|
204
|
+
lease_policy: LeasePolicy,
|
|
205
|
+
touch_ttl: Optional[int] = None,
|
|
206
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
207
|
+
lease_wait_fn: Optional[Callable[[float], None]] = None,
|
|
208
|
+
) -> Optional[Any]:
|
|
209
|
+
# A hot cache hit needs no lease: the value is already local and there
|
|
210
|
+
# is nothing to repopulate. Only the requests that fall through to the
|
|
211
|
+
# server take part in the lease.
|
|
212
|
+
return self._hot_cache_get(
|
|
213
|
+
key=key,
|
|
214
|
+
touch_ttl=touch_ttl,
|
|
215
|
+
recache_policy=recache_policy,
|
|
216
|
+
lease_policy=lease_policy,
|
|
217
|
+
lease_wait_fn=lease_wait_fn,
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
def _hot_cache_get(
|
|
221
|
+
self,
|
|
222
|
+
key: Union[Key, str],
|
|
223
|
+
touch_ttl: Optional[int] = None,
|
|
224
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
225
|
+
lease_policy: Optional[LeasePolicy] = None,
|
|
226
|
+
lease_wait_fn: Optional[Callable[[float], None]] = None,
|
|
194
227
|
) -> Optional[Any]:
|
|
195
228
|
key = key if isinstance(key, Key) else Key(key)
|
|
196
229
|
if self._allowed_prefixes and not self._allowed_prefixes.prefixes(key.key):
|
|
@@ -203,12 +236,26 @@ class ProbabilisticHotCache(ClientWrapper):
|
|
|
203
236
|
if found:
|
|
204
237
|
return value
|
|
205
238
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
239
|
+
if lease_policy is not None:
|
|
240
|
+
result = self._get_or_lease(
|
|
241
|
+
key=key,
|
|
242
|
+
lease_policy=lease_policy,
|
|
243
|
+
touch_ttl=touch_ttl,
|
|
244
|
+
recache_policy=recache_policy,
|
|
245
|
+
lease_wait_fn=lease_wait_fn,
|
|
246
|
+
)
|
|
247
|
+
if result and result.value is None:
|
|
248
|
+
# Lease placeholder: we hold the lease, or we lost and ran out
|
|
249
|
+
# of retries. Behaves as a miss, and nothing worth promoting.
|
|
250
|
+
result = None
|
|
251
|
+
else:
|
|
252
|
+
result = self._get(
|
|
253
|
+
key=key,
|
|
254
|
+
touch_ttl=touch_ttl,
|
|
255
|
+
recache_policy=recache_policy,
|
|
256
|
+
return_cas_token=False,
|
|
257
|
+
)
|
|
258
|
+
|
|
212
259
|
if result is None:
|
|
213
260
|
allowed and self._metrics and self._metrics.metric_inc("candidate_misses")
|
|
214
261
|
is_hot and self._clear_hot_cache_if_necessary(key)
|
{meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/interfaces/high_level_commands.py
RENAMED
|
@@ -120,6 +120,13 @@ class HighLevelCommandsProtocol(Protocol):
|
|
|
120
120
|
recache_policy: Optional[RecachePolicy] = None,
|
|
121
121
|
) -> Dict[Key, Optional[Any]]: ... # pragma: no cover
|
|
122
122
|
|
|
123
|
+
def multi_get_cas(
|
|
124
|
+
self,
|
|
125
|
+
keys: Iterable[Union[Key, str]],
|
|
126
|
+
touch_ttl: Optional[int] = None,
|
|
127
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
128
|
+
) -> Dict[Key, Tuple[Optional[Any], Optional[int]]]: ... # pragma: no cover
|
|
129
|
+
|
|
123
130
|
def _multi_get(
|
|
124
131
|
self,
|
|
125
132
|
keys: Iterable[Union[Key, str]],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meta-memcache
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Modern, pure python, memcache client with support for new meta commands.
|
|
5
5
|
Author-email: Guillermo Perez <bisho@revenuecat.com>
|
|
6
6
|
License: MIT License
|
|
@@ -434,6 +434,17 @@ Invalidation...
|
|
|
434
434
|
Get multiple keys at once
|
|
435
435
|
"""
|
|
436
436
|
|
|
437
|
+
def multi_get_cas(
|
|
438
|
+
self,
|
|
439
|
+
keys: List[Union[Key, str]],
|
|
440
|
+
touch_ttl: Optional[int] = None,
|
|
441
|
+
recache_policy: Optional[RecachePolicy] = None,
|
|
442
|
+
) -> Dict[Key, Tuple[Optional[Any], Optional[int]]]:
|
|
443
|
+
"""
|
|
444
|
+
Same as multi_get(), but also return the CAS tokens so
|
|
445
|
+
they can be used during writes and detect races
|
|
446
|
+
"""
|
|
447
|
+
|
|
437
448
|
def get_cas(
|
|
438
449
|
self,
|
|
439
450
|
key: Union[Key, str],
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meta_memcache-2.3.0 → meta_memcache-2.5.0}/src/meta_memcache/extras/migrating_cache_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|