diff options
author | Peter Renstròˆm <renstrom.peter@gmail.com> | 2017-03-14 14:40:31 +0100 |
---|---|---|
committer | Peter Renstròˆm <renstrom.peter@gmail.com> | 2017-03-14 14:40:31 +0100 |
commit | 4782f033ba199e7bbc8b020061c3f75879d75c73 (patch) | |
tree | 5dcacf8fa4ae8af3e797fe5e20b1e982d1c24d51 | |
parent | 9b92bb726ae348eb3325bfdd6635d79f1b2813e2 (diff) | |
download | pymemcache-4782f033ba199e7bbc8b020061c3f75879d75c73.tar.gz |
Return default value instead of False when all clients are down
The documentation for `ignore_exc` says it will treat memcache/network
errors as cache misses (i.e. `None` for reads and `False` for writes).
However the short-circuit path for when no client can be used (because
they're all marked as down/bad) always returns `False`. This change
change the behaviour to return each command's default value instead.
I actually stumbled upon this because I wanted to inspect some behaviour
in a system without cache so I stopped all memcached nodes. Our code
looked something like this:
data = memcached_client.get(key)
if data is None:
return fetch_from_database(key)
else:
return json.loads(data)
What happened was that every once in a while I would see a stacktrace
because the `json.loads(data)` call would fail with a `TypeError`
because it tries to deserialize a bool (`False`).
-rw-r--r-- | pymemcache/client/hash.py | 2 | ||||
-rw-r--r-- | pymemcache/test/test_client_hash.py | 4 |
2 files changed, 4 insertions, 2 deletions
diff --git a/pymemcache/client/hash.py b/pymemcache/client/hash.py index 5e2d6ff..6c9c298 100644 --- a/pymemcache/client/hash.py +++ b/pymemcache/client/hash.py @@ -217,7 +217,7 @@ class HashClient(object): client = self._get_client(key) if client is None: - return False + return default_val func = getattr(client, cmd) args = list(args) diff --git a/pymemcache/test/test_client_hash.py b/pymemcache/test/test_client_hash.py index 30b2130..641eaed 100644 --- a/pymemcache/test/test_client_hash.py +++ b/pymemcache/test/test_client_hash.py @@ -177,7 +177,7 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): with pytest.raises(socket.error): client.get('foo') - def test_no_servers_left_with_commands(self): + def test_no_servers_left_with_commands_return_default_value(self): from pymemcache.client.hash import HashClient client = HashClient( [], use_pooling=True, @@ -186,6 +186,8 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): ) result = client.get('foo') + assert result is None + result = client.set('foo', 'bar') assert result is False def test_no_servers_left_with_set_many(self): |