Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8189)

Unified Diff: chrome/common/extensions/docs/server2/appengine_memcache.py

Issue 10829348: Extensions Docs Server: Large performance increase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: server is fast Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/appengine_memcache.py
diff --git a/chrome/common/extensions/docs/server2/appengine_memcache.py b/chrome/common/extensions/docs/server2/appengine_memcache.py
index ce01e8b52866880069f1f3a8d419f7e21fe25865..605ba71653d37181a5c801f5a3dbca66e7cd48ac 100644
--- a/chrome/common/extensions/docs/server2/appengine_memcache.py
+++ b/chrome/common/extensions/docs/server2/appengine_memcache.py
@@ -2,12 +2,44 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import time
+
from appengine_wrappers import memcache
+from future import Future
MEMCACHE_FILE_SYSTEM_READ = 'MemcacheFileSystem.Get'
MEMCACHE_FILE_SYSTEM_STAT = 'MemcacheFileSystem.Stat'
MEMCACHE_GITHUB_STAT = 'MemcacheGithub.Stat'
MEMCACHE_BRANCH_UTILITY = 'BranchUtility'
+MEMCACHE_FILE_SYSTEM_CACHE = 'MemcacheFileSystemCache'
+MEMCACHE_FILE_SYSTEM_CACHE_LISTING = 'MemcacheFileSystemCache.Listing'
+
+class _CacheEntry(object):
+ def __init__(self, value, expire_time):
+ self.value = value
+ self._never_expires = (expire_time == 0)
+ self._expiry = time.time() + expire_time
+
+ def HasExpired(self):
+ if self._never_expires:
+ return False
+ return time.time() > self._expiry
+
+class _AsyncGetFuture(object):
+ def __init__(self, cache, time, namespace, rpc=None, mapping=None):
not at google - send to devlin 2012/08/20 05:27:10 document these parameters? I had to read the code
cduvall 2012/08/20 21:28:09 Done.
+ self._cache = cache
+ self._time = time
+ self._namespace = namespace
+ self._rpc = rpc
+ self._mapping = mapping
+
+ def Get(self):
+ if self._rpc is not None:
+ result = self._rpc.get_result()
+ self._cache[self._namespace].update(
+ dict((k, _CacheEntry(v, self._time)) for k, v in result.iteritems()))
+ self._mapping.update(result)
not at google - send to devlin 2012/08/20 05:27:10 this only works if initial_mapping is not None, an
cduvall 2012/08/20 21:28:09 Done.
+ return self._mapping
class AppEngineMemcache(object):
not at google - send to devlin 2012/08/20 05:27:10 This all just got complicated. You're gonna hate
cduvall 2012/08/20 21:28:09 Done.
"""A wrapper around the standard App Engine memcache that enforces namespace
@@ -16,15 +48,71 @@ class AppEngineMemcache(object):
"""
def __init__(self, branch):
self._branch = branch
+ self._cache = {}
+
+ def _SetInMemory(self, key, value, namespace, time):
+ if namespace not in self._cache:
+ self._cache[namespace] = {}
+ self._cache[namespace][key] = _CacheEntry(value, time)
+
+ def _TryGAE(self, key, namespace, time):
+ result = memcache.get(key, namespace=namespace)
+ if result is not None:
+ self._SetInMemory(key, result, namespace, time)
+ return result
+
+ def _MakeNamespace(self, namespace):
+ return self._branch + '.' + namespace
+
+ def Set(self, key, value, namespace, time=300):
not at google - send to devlin 2012/08/20 05:27:10 define 300 as a constant somewhere?
cduvall 2012/08/20 21:28:09 Done.
+ namespace = self._MakeNamespace(namespace)
+ self._SetInMemory(key, value, namespace, time)
+ memcache.set(key, value, namespace=namespace, time=time)
not at google - send to devlin 2012/08/20 05:27:10 this can be an async set, right? We don't care abo
cduvall 2012/08/20 21:28:09 There isn't a set_async function in memcache, only
+
+ def SetMulti(self, mapping, namespace, time=300):
+ namespace = self._MakeNamespace(namespace)
+ for k, v in mapping.iteritems():
+ self._SetInMemory(k, v, namespace, time)
+ # Use a batch set? App Engine kept throwing:
+ # ValueError: Values may not be more than 1000000 bytes in length
not at google - send to devlin 2012/08/20 05:27:10 Interesting. Yeah make this a TODO. If it's an as
cduvall 2012/08/20 21:28:09 Done.
+ # for the batch set.
+ self.Set(k, v, namespace, time=time)
- def Set(self, key, value, namespace, time=60):
- return memcache.set(key,
- value,
- namespace=self._branch + '.' + namespace,
- time=time)
+ def Get(self, key, namespace, time=300):
+ namespace = self._MakeNamespace(namespace)
+ if namespace not in self._cache:
+ return self._TryGAE(key, namespace, time)
+ cache_entry = self._cache[namespace].get(key, None)
+ if not cache_entry:
+ return self._TryGAE(key, namespace, time)
+ if cache_entry.HasExpired():
+ self._cache[namespace].pop(key)
+ return memcache.get(key, namespace=namespace)
+ return cache_entry.value
- def Get(self, key, namespace):
- return memcache.get(key, namespace=self._branch + '.' + namespace)
+ def GetMulti(self, keys, namespace, time=300):
+ namespace = self._MakeNamespace(namespace)
+ keys = keys[:]
+ mapping = {}
+ if namespace not in self._cache:
+ self._cache[namespace] = {}
+ for key in keys:
+ cache_entry = self._cache[namespace].get(key, None)
+ if cache_entry is not None and not cache_entry.HasExpired():
not at google - send to devlin 2012/08/20 05:27:10 nit: reverse the condition to make this more reada
cduvall 2012/08/20 21:28:09 Done.
+ mapping[key] = cache_entry.value
+ keys.remove(key)
+ else:
+ mapping[key] = None
+ client = memcache.Client()
+ rpc = client.get_multi_async(keys, namespace=namespace)
+ return Future(delegate=_AsyncGetFuture(self._cache,
+ time,
+ namespace,
+ rpc=rpc,
+ mapping=mapping))
def Delete(self, key, namespace):
- return memcache.delete(key, namespace=self._branch + '.' + namespace)
+ namespace = self._MakeNamespace(namespace)
+ if namespace in self._cache:
+ self._cache[namespace].pop(key)
+ memcache.delete(key, namespace=namespace)

Powered by Google App Engine
This is Rietveld 408576698