Merge lp:~leonardr/lazr.restful/disable-cache into lp:lazr.restful

Proposed by Leonard Richardson
Status: Merged
Merged at revision: 133
Proposed branch: lp:~leonardr/lazr.restful/disable-cache
Merge into: lp:lazr.restful
Diff against target: 163 lines (+94/-12)
4 files modified
src/lazr/restful/NEWS.txt (+7/-2)
src/lazr/restful/_resource.py (+21/-9)
src/lazr/restful/example/base/tests/representation-cache.txt (+59/-1)
src/lazr/restful/interfaces/_rest.py (+7/-0)
To merge this branch: bzr merge lp:~leonardr/lazr.restful/disable-cache
Reviewer Review Type Date Requested Status
LAZR Developers Pending
Review via email: mp+26713@code.launchpad.net

Description of the change

This branch adds a configuration option enable_server_side_representation_cache, which lets you disable the representation cache without un-registering it. I'll be using this to control the memcached representation cache in Launchpad with a Launchpad configuration setting. I have two goals.

1) Make it possible to test the cache in staging without having to deploy different code to staging and production.
2) Make it easy for the LOSAs to disable the cache if something goes wrong in production.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/lazr/restful/NEWS.txt'
--- src/lazr/restful/NEWS.txt 2010-06-02 17:04:40 +0000
+++ src/lazr/restful/NEWS.txt 2010-06-03 14:51:24 +0000
@@ -2,8 +2,13 @@
2NEWS for lazr.restful2NEWS for lazr.restful
3=====================3=====================
44
50.9.28 (Development)50.9.28 (2010-06-03)
6====================6===================
7
8Special note: This version adds a new configuration element,
9'enable_server_side_representation_cache'. This lets you turn the
10representation cache on and off at runtime without unregistering the
11cache utility.
712
8Fixed some test failures.13Fixed some test failures.
914
1015
=== modified file 'src/lazr/restful/_resource.py'
--- src/lazr/restful/_resource.py 2010-06-03 14:26:13 +0000
+++ src/lazr/restful/_resource.py 2010-06-03 14:51:24 +0000
@@ -1527,22 +1527,21 @@
1527 if media_type in [self.WADL_TYPE, self.DEPRECATED_WADL_TYPE]:1527 if media_type in [self.WADL_TYPE, self.DEPRECATED_WADL_TYPE]:
1528 return self.toWADL().encode("utf-8")1528 return self.toWADL().encode("utf-8")
1529 elif media_type == self.JSON_TYPE:1529 elif media_type == self.JSON_TYPE:
1530 cache = None1530 cache = self._representation_cache
1531 try:1531 if cache is None:
1532 cache = getUtility(IRepresentationCache)1532 representation = None
1533 else:
1533 representation = cache.get(1534 representation = cache.get(
1534 self.context, self.JSON_TYPE, self.request.version)1535 self.context, self.JSON_TYPE, self.request.version)
1535 except ComponentLookupError:
1536 # There's no representation cache.
1537 representation = None
15381536
1539 redacted_fields = self.redacted_fields1537 redacted_fields = self.redacted_fields
1540 if representation is None:1538 if representation is None:
1541 # Either there is no cache, or the representation1539 # Either there is no active cache, or the representation
1542 # wasn't in the cache.1540 # wasn't in the cache.
1543 representation = simplejson.dumps(self, cls=ResourceJSONEncoder)1541 representation = simplejson.dumps(self, cls=ResourceJSONEncoder)
1544 # If there's a cache, and this representation doesn't1542 # If there's an active cache, and this representation
1545 # contain any redactions, store it in the cache.1543 # doesn't contain any redactions, store it in the
1544 # cache.
1546 if cache is not None and len(redacted_fields) == 0:1545 if cache is not None and len(redacted_fields) == 0:
1547 cache.set(self.context, self.JSON_TYPE,1546 cache.set(self.context, self.JSON_TYPE,
1548 self.request.version, representation)1547 self.request.version, representation)
@@ -1569,6 +1568,19 @@
1569 "No representation implementation for media type %s"1568 "No representation implementation for media type %s"
1570 % media_type)1569 % media_type)
15711570
1571 @property
1572 def _representation_cache(self):
1573 """Return the representation cache, or None if missing/disabled."""
1574 try:
1575 cache = getUtility(IRepresentationCache)
1576 except ComponentLookupError:
1577 # There's no representation cache.
1578 return None
1579 config = getUtility(IWebServiceConfiguration)
1580 if config.enable_server_side_representation_cache:
1581 return cache
1582 return None
1583
15721584
1573class CollectionResource(BatchingResourceMixin,1585class CollectionResource(BatchingResourceMixin,
1574 CustomOperationResourceMixin,1586 CustomOperationResourceMixin,
15751587
=== modified file 'src/lazr/restful/example/base/tests/representation-cache.txt'
--- src/lazr/restful/example/base/tests/representation-cache.txt 2010-05-24 13:52:30 +0000
+++ src/lazr/restful/example/base/tests/representation-cache.txt 2010-06-03 14:51:24 +0000
@@ -259,7 +259,65 @@
259 This representation is from the cache.259 This representation is from the cache.
260 This representation is from the cache.260 This representation is from the cache.
261261
262Cleanup: de-register the cache.262enable_server_side_representation_cache
263=======================================
264
265A configuration setting allows you to disable the cache without
266de-registering it. This is useful when you're debugging a cache
267implementation or a cache invalidation algorithm.
268
269 >>> from lazr.restful.interfaces import IWebServiceConfiguration
270 >>> config = getUtility(IWebServiceConfiguration)
271 >>> print config.enable_server_side_representation_cache
272 True
273
274Set this configuration value to False, and representations will not be
275served from the cache, even if present.
276
277 >>> config.enable_server_side_representation_cache = False
278 >>> recipes = webservice.get("/recipes").jsonBody()['entries']
279 >>> for instructions in (
280 ... sorted(recipe['instructions'] for recipe in recipes)):
281 ... print instructions
282 A perfectly roasted chicken is...
283 Draw, singe, stuff, and truss...
284 Preheat oven to...
285 You can always judge...
286
287New representations will not be added to the cache.
288
289 >>> before_keys = len(dictionary.keys())
290 >>> dishes = webservice.get("/dishes")
291 >>> len(dictionary.keys()) == before_keys
292 True
293
294The cache is still registered as a utility.
295
296 >>> print getUtility(IRepresentationCache)
297 <lazr.restful.simple.DictionaryBasedRepresentationCache object ...>
298
299And it's still populated, as we can see by re-enabling it.
300
301 >>> config.enable_server_side_representation_cache = True
302 >>> recipes = webservice.get("/recipes").jsonBody()['entries']
303 >>> for instructions in (
304 ... sorted(recipe['instructions'] for recipe in recipes)):
305 ... print instructions
306 This representation is from the cache.
307 This representation is from the cache.
308 This representation is from the cache.
309 This representation is from the cache.
310
311Once re-enabled, new representations are once again added to the cache.
312
313 >>> dishes = webservice.get("/dishes")
314 >>> len(dictionary.keys()) > before_keys
315 True
316
317Cleanup
318=======
319
320De-register the cache.
263321
264 >>> sm.registerUtility(None, IRepresentationCache)322 >>> sm.registerUtility(None, IRepresentationCache)
265323
266324
=== modified file 'src/lazr/restful/interfaces/_rest.py'
--- src/lazr/restful/interfaces/_rest.py 2010-05-24 13:00:07 +0000
+++ src/lazr/restful/interfaces/_rest.py 2010-06-03 14:51:24 +0000
@@ -409,6 +409,13 @@
409 service root for the latest version (which probably changes more409 service root for the latest version (which probably changes more
410 often).""")410 often).""")
411411
412 enable_server_side_representation_cache = Bool(
413 title=u"Enable the server-side representation cache.",
414 default=True,
415 description=u"""If this is false, the server-side representation
416 cache will not be used, even if one is registered."""
417 )
418
412 service_description = TextLine(419 service_description = TextLine(
413 title=u"Service description",420 title=u"Service description",
414 description=u"""A human-readable description of the web service.421 description=u"""A human-readable description of the web service.

Subscribers

People subscribed via source and target branches