summaryrefslogtreecommitdiff
path: root/pymemcache/client
diff options
context:
space:
mode:
Diffstat (limited to 'pymemcache/client')
-rw-r--r--pymemcache/client/base.py64
-rw-r--r--pymemcache/client/hash.py26
2 files changed, 83 insertions, 7 deletions
diff --git a/pymemcache/client/base.py b/pymemcache/client/base.py
index 04ae052..252e860 100644
--- a/pymemcache/client/base.py
+++ b/pymemcache/client/base.py
@@ -688,6 +688,23 @@ class Client:
key, default
)
+ def gat(self, key: Key, expire: int = 0, default: Optional[Any] = None) -> Any:
+ """
+ The memcached "gat" command, but only for one key, as a convenience.
+
+ Args:
+ key: str, see class docs for details.
+ expire: optional int, number of seconds until the item is expired
+ from the cache, or zero for no expiry (the default).
+ default: value that will be returned if the key was not found.
+
+ Returns:
+ The value for the key, or default if the key wasn't found.
+ """
+ return self._fetch_cmd(
+ b"gat", [key], False, key_prefix=self.key_prefix, expire=expire
+ ).get(key, default)
+
def get_many(self, keys: Iterable[Key]) -> Dict[Key, Any]:
"""
The memcached "get" command.
@@ -727,6 +744,28 @@ class Client:
key, defaults
)
+ def gats(
+ self, key: Key, expire: int = 0, default: Any = None, cas_default: Any = None
+ ) -> Tuple[Any, Any]:
+ """
+ The memcached "gats" command, but only for one key, as a convenience.
+
+ Args:
+ key: str, see class docs for details.
+ expire: optional int, number of seconds until the item is expired
+ from the cache, or zero for no expiry (the default).
+ default: value that will be returned if the key was not found.
+ cas_default: same behaviour as default argument.
+
+ Returns:
+ A tuple of (value, cas)
+ or (default, cas_defaults) if the key was not found.
+ """
+ defaults = (default, cas_default)
+ return self._fetch_cmd(
+ b"gats", [key], True, key_prefix=self.key_prefix, expire=expire
+ ).get(key, defaults)
+
def gets_many(self, keys: Iterable[Key]) -> Dict[Key, Tuple[Any, Any]]:
"""
The memcached "gets" command.
@@ -1118,12 +1157,17 @@ class Client:
keys: Iterable[Key],
expect_cas: bool,
key_prefix: bytes = b"",
+ expire: Optional[int] = None,
) -> Dict[Key, Any]:
prefixed_keys = [self.check_key(k, key_prefix=key_prefix) for k in keys]
remapped_keys = dict(zip(prefixed_keys, keys))
# It is important for all keys to be listed in their original order.
cmd = name
+ if expire is not None:
+ expire_bytes = self._check_integer(expire, "expire")
+ cmd += b" " + expire_bytes
+
if prefixed_keys:
cmd += b" " + b" ".join(prefixed_keys)
cmd += b"\r\n"
@@ -1498,6 +1542,26 @@ class PooledClient:
else:
raise
+ def gat(self, key: Key, expire: int = 0, default: Optional[Any] = None) -> Any:
+ with self.client_pool.get_and_release(destroy_on_fail=True) as client:
+ try:
+ return client.gat(key, expire, default)
+ except Exception:
+ if self.ignore_exc:
+ return default
+ else:
+ raise
+
+ def gats(self, key: Key, expire: int = 0, default: Optional[Any] = None) -> Any:
+ with self.client_pool.get_and_release(destroy_on_fail=True) as client:
+ try:
+ return client.gats(key, expire, default)
+ except Exception:
+ if self.ignore_exc:
+ return default
+ else:
+ raise
+
def get_many(self, keys: Iterable[Key]) -> Dict[Key, Any]:
with self.client_pool.get_and_release(destroy_on_fail=True) as client:
try:
diff --git a/pymemcache/client/hash.py b/pymemcache/client/hash.py
index e56517f..aec4090 100644
--- a/pymemcache/client/hash.py
+++ b/pymemcache/client/hash.py
@@ -170,18 +170,24 @@ class HashClient:
self._last_dead_check_time = current_time
def _get_client(self, key):
- check_key_helper(key, self.allow_unicode_keys, self.key_prefix)
+ # If key is tuple use first item as server key
+ if isinstance(key, tuple) and len(key) == 2:
+ server_key, key = key
+ else:
+ server_key = key
+
+ check_key_helper(server_key, self.allow_unicode_keys, self.key_prefix)
if self._dead_clients:
self._retry_dead()
- server = self.hasher.get_node(key)
+ server = self.hasher.get_node(server_key)
# We've ran out of servers to try
if server is None:
if self.ignore_exc is True:
- return
+ return None, key
raise MemcacheError("All servers seem to be down right now")
- return self.clients[server]
+ return self.clients[server], key
def _safely_run_func(self, client, func, default_val, *args, **kwargs):
try:
@@ -311,7 +317,7 @@ class HashClient:
self._failed_clients[server] = failed_metadata
def _run_cmd(self, cmd, key, default_val, *args, **kwargs):
- client = self._get_client(key)
+ client, key = self._get_client(key)
if client is None:
return default_val
@@ -346,6 +352,12 @@ class HashClient:
def get(self, key, default=None, **kwargs):
return self._run_cmd("get", key, default, default=default, **kwargs)
+ def gat(self, key, default=None, **kwargs):
+ return self._run_cmd("gat", key, default, default=default, **kwargs)
+
+ def gats(self, key, default=None, **kwargs):
+ return self._run_cmd("gats", key, default, default=default, **kwargs)
+
def incr(self, key, *args, **kwargs):
return self._run_cmd("incr", key, False, *args, **kwargs)
@@ -357,7 +369,7 @@ class HashClient:
failed = []
for key, value in values.items():
- client = self._get_client(key)
+ client, key = self._get_client(key)
if client is None:
failed.append(key)
@@ -378,7 +390,7 @@ class HashClient:
end = {}
for key in keys:
- client = self._get_client(key)
+ client, key = self._get_client(key)
if client is None:
continue