From 34bab49716e44a8071640c7ca05a6cbe8937130d Mon Sep 17 00:00:00 2001 From: Kazuhiko Shiozaki <kazuhiko@nexedi.com> Date: Wed, 27 Oct 2010 09:48:21 +0000 Subject: [PATCH] memcache.Client._get() should raises an Exception instead of returning None, in case of connection errors or missing values. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@39557 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5Type/Tool/MemcachedTool.py | 7 ++- product/ERP5Type/patches/memcache_client.py | 52 +++++++++++++++++++-- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/product/ERP5Type/Tool/MemcachedTool.py b/product/ERP5Type/Tool/MemcachedTool.py index 2258968b4c..f48053a297 100644 --- a/product/ERP5Type/Tool/MemcachedTool.py +++ b/product/ERP5Type/Tool/MemcachedTool.py @@ -171,12 +171,11 @@ if memcache is not None: encoded_key = encodeKey(key) result = self.local_cache.get(key, MARKER) if result is MARKER: - result = self.memcached_connection.get(encoded_key) - if result is None: + try: + result = self.memcached_connection.get(encoded_key) + except memcache.Client.MemcachedConnectionError: self._initialiseConnection() result = self.memcached_connection.get(encoded_key) - if result is None: - raise KeyError, 'Key %s (was %s) not found.' % (encoded_key, key) self.local_cache[key] = result return result diff --git a/product/ERP5Type/patches/memcache_client.py b/product/ERP5Type/patches/memcache_client.py index c3f9441570..7c740e3e38 100644 --- a/product/ERP5Type/patches/memcache_client.py +++ b/product/ERP5Type/patches/memcache_client.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- # Code based on python-memcached-1.45 try: - import memcache + from memcache import _Host, Client, _Error except ImportError: pass else: - memcache._Host._SOCKET_TIMEOUT = 10 # wait more than 3s is safe + _Host._SOCKET_TIMEOUT = 10 # wait more than 3s is safe # always return string # https://bugs.launchpad.net/python-memcached/+bug/509712 def readline(self): @@ -20,8 +20,52 @@ else: self.mark_dead('Connection closed while reading from %s' % repr(self)) self.buffer = '' - return '' #None + # (patch) + # return None + return '' buf += data self.buffer = buf[index+2:] return buf[:index] - memcache._Host.readline = readline + _Host.readline = readline + + # Client._get() should raises an Exception instead of returning + # None, in case of connection errors or missing values. + class MemcachedConnectionError(Exception): + pass + Client.MemcachedConnectionError = MemcachedConnectionError + + import socket + def _get(self, cmd, key): + self.check_key(key) + server, key = self._get_server(key) + if not server: + # (patch) + # return None + raise MemcachedConnectionError + self._statlog(cmd) + + try: + server.send_cmd("%s %s" % (cmd, key)) + rkey = flags = rlen = cas_id = None + if cmd == 'gets': + rkey, flags, rlen, cas_id, = self._expect_cas_value(server) + if rkey: + self.cas_ids[rkey] = cas_id + else: + rkey, flags, rlen, = self._expectvalue(server) + + if not rkey: + # (patch) + # return None + raise KeyError + value = self._recv_value(server, flags, rlen) + server.expect("END") + except (_Error, socket.error), msg: + if isinstance(msg, tuple): msg = msg[1] + server.mark_dead(msg) + # (patch) + # return None + raise MemcachedConnectionError + return value + + Client._get = _get -- 2.30.9