diff options
author | Jenkins <jenkins@review.openstack.org> | 2015-04-20 19:07:51 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2015-04-20 19:07:51 +0000 |
commit | d8bed1986e7127223e53a8022f5fe066d410750f (patch) | |
tree | 47974466ee41d74eff6997fd4599ff2a44ec372e | |
parent | c340b7dd4dd862d9500478bfa3ed2dcb1054d5fe (diff) | |
parent | 18ca7fabece4837ad56e435bc9d5f0b6278fa4be (diff) | |
download | keystone-d8bed1986e7127223e53a8022f5fe066d410750f.tar.gz |
Merge "Make memcache client reusable across threads" into stable/kilo
-rw-r--r-- | keystone/common/cache/_memcache_pool.py | 21 | ||||
-rw-r--r-- | keystone/tests/unit/common/test_connection_pool.py | 16 |
2 files changed, 32 insertions, 5 deletions
diff --git a/keystone/common/cache/_memcache_pool.py b/keystone/common/cache/_memcache_pool.py index b15332db0..bc559781a 100644 --- a/keystone/common/cache/_memcache_pool.py +++ b/keystone/common/cache/_memcache_pool.py @@ -35,11 +35,22 @@ from keystone.i18n import _ LOG = log.getLogger(__name__) -# This 'class' is taken from http://stackoverflow.com/a/22520633/238308 -# Don't inherit client from threading.local so that we can reuse clients in -# different threads -_MemcacheClient = type('_MemcacheClient', (object,), - dict(memcache.Client.__dict__)) + +class _MemcacheClient(memcache.Client): + """Thread global memcache client + + As client is inherited from threading.local we have to restore object + methods overloaded by threading.local so we can reuse clients in + different threads + """ + __delattr__ = object.__delattr__ + __getattribute__ = object.__getattribute__ + __new__ = object.__new__ + __setattr__ = object.__setattr__ + + def __del__(self): + pass + _PoolItem = collections.namedtuple('_PoolItem', ['ttl', 'connection']) diff --git a/keystone/tests/unit/common/test_connection_pool.py b/keystone/tests/unit/common/test_connection_pool.py index 74d0420ce..3813e0339 100644 --- a/keystone/tests/unit/common/test_connection_pool.py +++ b/keystone/tests/unit/common/test_connection_pool.py @@ -10,9 +10,11 @@ # License for the specific language governing permissions and limitations # under the License. +import threading import time import mock +import six from six.moves import queue import testtools from testtools import matchers @@ -117,3 +119,17 @@ class TestConnectionPool(core.TestCase): # after it is available. connection_pool.put_nowait(conn) _acquire_connection() + + +class TestMemcacheClientOverrides(core.BaseTestCase): + + def test_client_stripped_of_threading_local(self): + """threading.local overrides are restored for _MemcacheClient""" + client_class = _memcache_pool._MemcacheClient + # get the genuine thread._local from MRO + thread_local = client_class.__mro__[2] + self.assertTrue(thread_local is threading.local) + for field in six.iterkeys(thread_local.__dict__): + if field not in ('__dict__', '__weakref__'): + self.assertNotEqual(id(getattr(thread_local, field, None)), + id(getattr(client_class, field, None))) |