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

Side by Side Diff: chrome/common/extensions/docs/server2/in_memory_object_store.py

Issue 13470005: Refactor the devserver to make it easier to control caching (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cduvall, rebase Created 7 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import time 5 import time
6 6
7 from appengine_wrappers import CACHE_TIMEOUT 7 from appengine_wrappers import CACHE_TIMEOUT
8 from future import Future 8 from future import Future
9 from object_store import ObjectStore 9 from object_store import ObjectStore
10 from memcache_object_store import MemcacheObjectStore
11 10
12 class _CacheEntry(object): 11 class _CacheEntry(object):
13 def __init__(self, value, expire_time): 12 def __init__(self, value, expire_time):
14 self.value = value 13 self.value = value
15 self._never_expires = (expire_time == 0) 14 self._never_expires = (expire_time == 0)
16 self._expiry = time.time() + expire_time 15 self._expiry = time.time() + expire_time
17 16
18 def HasExpired(self): 17 def HasExpired(self):
19 if self._never_expires: 18 if self._never_expires:
20 return False 19 return False
21 return time.time() > self._expiry 20 return time.time() > self._expiry
22 21
23 class _AsyncGetFuture(object): 22 class _AsyncGetFuture(object):
24 """A future for memcache gets. 23 """A future for memcache gets.
25 24
26 Properties: 25 Properties:
27 - |cache| the in-memory cache used by InMemoryObjectStore 26 - |cache| the in-memory cache used by InMemoryObjectStore
28 - |time| the cache timeout 27 - |time| the cache timeout
29 - |namespace| the namespace of the cache items
30 - |future| the |Future| from the backing |ObjectStore| 28 - |future| the |Future| from the backing |ObjectStore|
31 - |initial_mapping| a mapping of cache items already in memory 29 - |initial_mapping| a mapping of cache items already in memory
32 """ 30 """
33 def __init__(self, cache, time, namespace, future, initial_mapping): 31 def __init__(self, cache, time, future, initial_mapping):
34 self._cache = cache 32 self._cache = cache
35 self._time = time 33 self._time = time
36 self._namespace = namespace
37 self._future = future 34 self._future = future
38 self._mapping = initial_mapping 35 self._mapping = initial_mapping
39 36
40 def Get(self): 37 def Get(self):
41 if self._future is not None: 38 if self._future is not None:
42 result = self._future.Get() 39 result = self._future.Get()
43 self._cache[self._namespace].update( 40 self._cache.update(
44 dict((k, _CacheEntry(v, self._time)) for k, v in result.iteritems())) 41 dict((k, _CacheEntry(v, self._time)) for k, v in result.iteritems()))
45 self._mapping.update(result) 42 self._mapping.update(result)
46 return self._mapping 43 return self._mapping
47 44
48 class InMemoryObjectStore(ObjectStore): 45 class InMemoryObjectStore(ObjectStore):
49 def __init__(self, branch): 46 def __init__(self, object_store):
50 self._branch = branch 47 self._object_store = object_store
51 self._cache = {} 48 self._cache = {}
52 self._object_store = MemcacheObjectStore()
53 49
54 def _MakeNamespace(self, namespace): 50 def SetMulti(self, mapping, time=CACHE_TIMEOUT):
55 return 'ObjectStore.%s.%s' % (self._branch, namespace)
56
57 def SetMulti(self, mapping, namespace, time=CACHE_TIMEOUT):
58 namespace = self._MakeNamespace(namespace)
59 for k, v in mapping.iteritems(): 51 for k, v in mapping.iteritems():
60 if namespace not in self._cache: 52 self._cache[k] = _CacheEntry(v, time)
61 self._cache[namespace] = {}
62 self._cache[namespace][k] = _CacheEntry(v, time)
63 # TODO(cduvall): Use a batch set? App Engine kept throwing: 53 # TODO(cduvall): Use a batch set? App Engine kept throwing:
64 # ValueError: Values may not be more than 1000000 bytes in length 54 # ValueError: Values may not be more than 1000000 bytes in length
65 # for the batch set. 55 # for the batch set.
66 self._object_store.Set(k, v, namespace, time=time) 56 self._object_store.Set(k, v, time=time)
67 57
68 def GetMulti(self, keys, namespace, time=CACHE_TIMEOUT): 58 def GetMulti(self, keys, time=CACHE_TIMEOUT):
69 namespace = self._MakeNamespace(namespace)
70 keys = keys[:] 59 keys = keys[:]
71 mapping = {} 60 mapping = {}
72 if namespace not in self._cache:
73 self._cache[namespace] = {}
74 for key in keys: 61 for key in keys:
75 cache_entry = self._cache[namespace].get(key, None) 62 cache_entry = self._cache.get(key, None)
76 if cache_entry is None or cache_entry.HasExpired(): 63 if cache_entry is None or cache_entry.HasExpired():
77 mapping[key] = None 64 mapping[key] = None
78 else: 65 else:
79 mapping[key] = cache_entry.value 66 mapping[key] = cache_entry.value
80 keys.remove(key) 67 keys.remove(key)
81 future = self._object_store.GetMulti(keys, namespace, time=time) 68 future = self._object_store.GetMulti(keys, time=time)
82 return Future(delegate=_AsyncGetFuture(self._cache, 69 return Future(delegate=_AsyncGetFuture(self._cache,
83 time, 70 time,
84 namespace,
85 future, 71 future,
86 mapping)) 72 mapping))
87 73
88 def Delete(self, key, namespace): 74 def Delete(self, key):
89 namespace = self._MakeNamespace(namespace) 75 if key in self._cache:
90 if namespace in self._cache and key in self._cache[namespace]: 76 self._cache.pop(key)
91 self._cache[namespace].pop(key) 77 self._object_store.Delete(key)
92 self._object_store.Delete(key, namespace)
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/handler.py ('k') | chrome/common/extensions/docs/server2/integration_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698