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