[CalendarServer-changes] [3983] CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/ memcacheprops.py
source_changes at macosforge.org
source_changes at macosforge.org
Sat Apr 11 14:21:35 PDT 2009
Revision: 3983
http://trac.macosforge.org/projects/calendarserver/changeset/3983
Author: wsanchez at apple.com
Date: 2009-04-11 14:21:33 -0700 (Sat, 11 Apr 2009)
Log Message:
-----------
Appears to be working now.
Modified Paths:
--------------
CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/memcacheprops.py
Modified: CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/memcacheprops.py
===================================================================
--- CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/memcacheprops.py 2009-04-11 19:02:50 UTC (rev 3982)
+++ CalendarServer/branches/users/wsanchez/mo-cache/twistedcaldav/memcacheprops.py 2009-04-11 21:21:33 UTC (rev 3983)
@@ -39,8 +39,10 @@
from twisted.web2.http import HTTPError, StatusResponse
from twistedcaldav.config import config
-from twistedcaldav.log import LoggingMixIn
+from twistedcaldav.log import LoggingMixIn, Logger
+log = Logger()
+
NoValue = ""
class MemcachePropertyStore (LoggingMixIn):
@@ -54,6 +56,7 @@
self.cacheTimeout = cacheTimeout
def _getMemcacheClient(self, refresh=False):
+ raise NotImplementedError()
if not config.Memcached.ClientEnabled:
# Not allowed to switch form caching to not caching
assert not hasattr(self, self._memcacheClient)
@@ -190,28 +193,41 @@
class MemcachePropertyCollection (LoggingMixIn):
"""
- Manages a single property store for resources in a collection.
+ Manages a single property store for all resources in a collection.
"""
def __init__(self, collection, cacheTimeout=0):
self.collection = collection
self.cacheTimeout = cacheTimeout
- def _getMemcacheClient(self, refresh=False):
- if not config.Memcached.ClientEnabled:
- # Not allowed to switch form caching to not caching
- assert not hasattr(self, self._memcacheClient)
- return None
+ @classmethod
+ def memcacheClient(cls, refresh=False):
+ if not hasattr(MemcachePropertyCollection, "_memcacheClient"):
+ if not config.Memcached.ClientEnabled:
+ return None
- if refresh or not hasattr(self, "_memcacheClient"):
- self._memcacheClient = MemcacheClient(
+ log.info("Instantiating memcache connection for MemcachePropertyCollection")
+ MemcachePropertyCollection._memcacheClient = MemcacheClient(
["%s:%s" % (config.Memcached.BindAddress, config.Memcached.Port)],
debug=0,
pickleProtocol=2,
)
- assert self._memcacheClient is not None
- return self._memcacheClient
+ assert MemcachePropertyCollection._memcacheClient is not None
+ return MemcachePropertyCollection._memcacheClient
+
def propertyCache(self):
+ # The property cache has this format:
+ # {
+ # "/path/to/resource/file":
+ # (
+ # {
+ # (namespace, name): property,
+ # ...,
+ # },
+ # memcache_token,
+ # ),
+ # ...,
+ # }
if not hasattr(self, "_propertyCache"):
self._propertyCache = self._loadCache()
return self._propertyCache
@@ -235,7 +251,7 @@
self.log_debug("Loading cache for %s" % (self.collection,))
- client = self._getMemcacheClient()
+ client = self.memcacheClient()
assert client is not None, "OMG no cache!"
if client is None:
return None
@@ -261,10 +277,6 @@
result.update(loaded.iteritems())
- print "#"*50, "Result:"
- print result
- print "#"*50
-
return result
def _storeCache(self, cache):
@@ -276,7 +288,7 @@
in cache.iteritems()
))
- client = self._getMemcacheClient()
+ client = self.memcacheClient()
if client is not None:
client.set_multi(values, time=self.cacheTimeout)
@@ -307,29 +319,47 @@
def setProperty(self, child, property):
path = child.fp.path
key = self._keyForPath(path)
- childCache = self.propertyCache().get(key, (None, None))[0]
+ propertyCache = self.propertyCache()
+ childCache, token = propertyCache.get(key, (None, None))
- print "*"*40
- print path, key, childCache, self.propertyCache()
- print "*"*40
-
assert childCache is not None, "No child cache?"
- currentValue, token = childCache.get(property.qname(), (None, None))
-
- if currentValue == property:
+ if childCache.get(property.qname(), None) == property:
+ # No changes
return
- client = self._getMemcacheClient()
+ childCache[property.qname()] = property
+
+ client = self.memcacheClient()
if client is not None:
- if property is None:
- client.delete(key)
- else:
- result = client.set(key, property, time=self.cacheTimeout, token=token)
- assert result, "Unable to set property"
- del self.propertyCache()[path]
- self._loadCache(childNames=(child.fp.basename(),))
+ result = client.set(key, childCache, time=self.cacheTimeout, token=token)
+ if not result:
+ delattr(self, "_propertyCache")
+ raise MemcacheError("Unable to set property")
+ loaded = self._loadCache(childNames=(child.fp.basename(),))
+ propertyCache.update(loaded.iteritems())
+
+ def deleteProperty(self, child, qname):
+ path = child.fp.path
+ key = self._keyForPath(path)
+ propertyCache = self.propertyCache()
+ childCache, token = propertyCache.get(key, (None, None))
+
+ assert childCache is not None, "No child cache?"
+
+ del childCache[qname]
+
+ client = self.memcacheClient()
+ if client is not None:
+ result = client.set(key, childCache, time=self.cacheTimeout, token=token)
+ if not result:
+ delattr(self, "_propertyCache")
+ raise MemcacheError("Unable to delete property")
+
+ loaded = self._loadCache(childNames=(child.fp.basename(),))
+ propertyCache.update(loaded.iteritems())
+
def propertyStoreForChild(self, child, childPropertyStore):
return self.ChildPropertyStore(self, child, childPropertyStore)
@@ -342,7 +372,8 @@
def propertyCache(self):
path = self.child.fp.path
key = self.parentPropertyCollection._keyForPath(path)
- return self.parentPropertyCollection.propertyCache().get(key, ({}, None))[0]
+ parentPropertyCache = self.parentPropertyCollection.propertyCache()
+ return parentPropertyCache.get(key, ({}, None))[0]
def get(self, qname, cache=True):
if cache:
@@ -370,13 +401,13 @@
self.log_debug("Delete for %s on %s"
% (qname, self.childPropertyStore.resource.fp.path))
- self.parentPropertyCollection.setProperty(self.child, None)
+ self.parentPropertyCollection.deleteProperty(self.child, qname)
self.childPropertyStore.delete(qname)
def contains(self, qname, cache=True):
if cache:
propertyCache = self.propertyCache()
- return qname in propertyCache.keys()
+ return qname in propertyCache
self.log_debug("Contains for %s"
% (self.childPropertyStore.resource.fp.path,))
@@ -385,7 +416,7 @@
def list(self, cache=True):
if cache:
propertyCache = self.propertyCache()
- return propertyCache.keys()
+ return propertyCache.iterkeys()
self.log_debug("List for %s"
% (self.childPropertyStore.resource.fp.path,))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090411/5867254c/attachment-0001.html>
More information about the calendarserver-changes
mailing list