[Checkins] SVN: lovely.memcached/trunk/ see CHANGES.txt
Bernd Dorn
bernd.dorn at lovelysystems.com
Tue Jul 3 11:54:09 EDT 2007
Log message for revision 77359:
see CHANGES.txt
Changed:
U lovely.memcached/trunk/CHANGES.txt
U lovely.memcached/trunk/src/lovely/memcached/testing/memcache.py
U lovely.memcached/trunk/src/lovely/memcached/utility.py
-=-
Modified: lovely.memcached/trunk/CHANGES.txt
===================================================================
--- lovely.memcached/trunk/CHANGES.txt 2007-07-03 15:18:06 UTC (rev 77358)
+++ lovely.memcached/trunk/CHANGES.txt 2007-07-03 15:54:09 UTC (rev 77359)
@@ -5,6 +5,9 @@
After 0.1.1
===========
+- refactor the storage implementation to prevent side effects when a
+ utility gets reloaded from zodb
+
- use a specific client uid for key tracking
- more logging
Modified: lovely.memcached/trunk/src/lovely/memcached/testing/memcache.py
===================================================================
--- lovely.memcached/trunk/src/lovely/memcached/testing/memcache.py 2007-07-03 15:18:06 UTC (rev 77358)
+++ lovely.memcached/trunk/src/lovely/memcached/testing/memcache.py 2007-07-03 15:54:09 UTC (rev 77359)
@@ -19,14 +19,25 @@
from datetime import datetime, timedelta
from lovely.memcached.utility import MemcachedClient
+import threading
+# the own client storage for testing
+TLOCAL = threading.local()
class TestMemcachedClient(MemcachedClient):
"""A memcache client which doesn't need a running memcache daemon"""
+ def __init__(self, *args, **kw):
+ super(TestMemcachedClient, self).__init__(*args, **kw)
+ # reset counts etc
+ self.resetCounts()
+
def _instantiateClient(self, debug):
return SimulatedMemcached()
+ def _storages(self):
+ return TLOCAL.__dict__
+
@property
def hits(self):
return self.client.hits
Modified: lovely.memcached/trunk/src/lovely/memcached/utility.py
===================================================================
--- lovely.memcached/trunk/src/lovely/memcached/utility.py 2007-07-03 15:18:06 UTC (rev 77358)
+++ lovely.memcached/trunk/src/lovely/memcached/utility.py 2007-07-03 15:54:09 UTC (rev 77359)
@@ -33,6 +33,8 @@
from interfaces import IMemcachedClient
from types import StringType
+TLOCAL = threading.local()
+
log = logging.getLogger('lovely.memcached')
# base namespace for key management
@@ -42,6 +44,9 @@
# namespace for deps
DEP_NS = NS + '.dep'
+class Storage(object):
+ pass
+
class MemcachedClient(persistent.Persistent):
interface.implements(IMemcachedClient)
@@ -50,7 +55,7 @@
defaultLifetime = FieldProperty(
IMemcachedClient['defaultLifetime'])
trackKeys = FieldProperty(IMemcachedClient['trackKeys'])
-
+
def __init__(self, servers=None, defaultAge=None,
defaultNS=None, trackKeys=None):
if servers is not None:
@@ -84,7 +89,7 @@
log.debug('set: %r, %r, %r, %r' % (key,
len(data), ns,
lifetime))
-
+
bKey = self._buildKey(key, ns, raw=raw)
if self.client.set(bKey, data, lifetime):
self._keysSet(key, ns, lifetime)
@@ -133,27 +138,27 @@
def invalidateAll(self):
# notice this does not look at namespaces
self.client.flush_all()
- if hasattr(self, '_v_storage'):
- del self._v_storage
+ key = (tuple(self.servers), self.trackKeys)
+ del self._storages()[key]
def _buildKey(self, key, ns, raw=False):
"""builds a key for key and ns, if key is a persistent
object its oid is used
-
+
>>> vc1 = MemcachedClient()
>>> k1 = vc1._buildKey(1, None)
of course the key is the same for same arguments
>>> k1 == vc1._buildKey(1, None)
True
-
+
the key is an md5 digest
>>> len(k1)
32
for different namespaces the keys are different
-
+
>>> vc2 = MemcachedClient()
>>> k2 = vc2._buildKey(1, u'vc2')
>>> k2 != k1
@@ -195,33 +200,38 @@
@property
def client(self):
- servers = getattr(self.storage, 'servers', None)
- if servers is not self.servers:
- # we have a change in the list of servers
- self.storage.client = None
- self.storage.servers = self.servers
+# servers = getattr(self.storage, 'servers', None)
+# if servers is not self.servers:
+# # we have a change in the list of servers
+# self.storage.client = None
+# self.storage.servers = self.servers
client = getattr(self.storage, 'client', None)
if client is None:
client = self._instantiateClient(debug=0)
self.storage.client = client
return client
+ def _storages(self):
+ return TLOCAL.__dict__
+
@property
def storage(self):
# we use a thread local storage to have a memcache client for every
# thread.
- if not hasattr(self, '_v_storage'):
+ key = (tuple(self.servers), self.trackKeys)
+ storage = self._storages().get(key)
+ if storage is None:
log.info('Creating new local storage')
- self._v_storage = threading.local()
- if self.trackKeys and not hasattr(self._v_storage, 'keys'):
+ storage = self._storages()[key] = Storage()
+ if self.trackKeys and not hasattr(storage, 'keys'):
tName = threading.currentThread().getName()
pid = os.getpid()
hostName = socket.gethostname()
uid = '%s-%s-%s' % (hostName,
pid,
tName)
- self._keysInit(self._v_storage, uid)
- return self._v_storage
+ self._keysInit(storage, uid)
+ return storage
def _instantiateClient(self, debug):
return memcache.Client(self.servers, debug=debug)
@@ -303,4 +313,4 @@
self.set(keys, (s.uid, ns), lifetime=0, ns=NS)
s.dirtyKeys.discard(ns)
s.lastUpdates[ns] = t
-
+
More information about the Checkins
mailing list