From b9a37a2dceca243fc962ab7d102f2bf1d999ed53 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Thu, 8 Oct 2020 17:37:25 +0200 Subject: [PATCH] Revert part of "Handling of legacy resource registries Products.ResourceRegistries removed" This partially reverts commit b18dedbe24658427799ef4909946971e6bb8e518. Specifically: - This reintroduces the resourceRegistries ETag in the various caching profiles. - Adds documentation for the ETag. - Adapts the tests to expect content for the ETag. The tests will need changes though. The legacy resource registries (portal_css/kss/javascript) are definitely not supported with this revert. This is only about the "new-style" Plone 5 resource registries in `@@resourceregistry-controlpanel`. --- docs/caching-proxies.rst | 11 +++++++++-- docs/etags.rst | 5 +++++ .../with-caching-proxy-splitviews/registry.xml | 4 +++- .../caching/profiles/with-caching-proxy/registry.xml | 2 ++ .../profiles/without-caching-proxy/registry.xml | 4 +++- .../caching/tests/test_profile_with_caching_proxy.py | 12 ++++++------ .../tests/test_profile_without_caching_proxy.py | 12 ++++++------ 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/docs/caching-proxies.rst b/docs/caching-proxies.rst index adb3780..f5955fc 100644 --- a/docs/caching-proxies.rst +++ b/docs/caching-proxies.rst @@ -22,7 +22,13 @@ returned to a user, because the cache has not been updated since the item was modified. There are three general strategies for dealing with this: * Since resources are cached in the proxy based on their URL, you can - "invalidate" the cached copy by changing an item's URL when it is updated. This approach has the benefit of also being able to + "invalidate" the cached copy by changing an item's URL when it is updated. + This is the approach taken by Plone's ResourceRegistries: + in production mode, the links that are inserted + into Plone's content pages for resource managed by ResourceRegistries + contain a time-based token, which changes when the ResourceRegistries + are updated, more specifically: when the resource bundles are combined. + This approach has the benefit of also being able to "invalidate" content stored in a user's browser cache. * All caching proxies support setting timeouts. This means that content may @@ -85,7 +91,8 @@ The default purge paths include: ``Image`` types. Files and images created (or customised) in the ZMI are purged automatically -when modified. To purge Plone content when modified +when modified. Files managed through the ResourceRegistries do not need +purging, since they have "stable" URLs. To purge Plone content when modified (or removed), you must select the content types in the control panel. By default, only the ``File`` and ``Image`` types are purged. diff --git a/docs/etags.rst b/docs/etags.rst index 9b842c3..3cdc796 100644 --- a/docs/etags.rst +++ b/docs/etags.rst @@ -42,6 +42,11 @@ The ETag names tokens supported by default are: * skin The name of the current skin (theme) +* resourceRegistries + A timestamp indicating the last-modified timestamp for the + Resource Registries. This is useful for avoiding requests for expired + resources from cached pages. + It is possible to provide additional tokens by registering an ``IETagValue`` adapter. This should be a named adapter on the published object (typically a view, file resource or Zope page template object) and request, with a unique diff --git a/plone/app/caching/profiles/with-caching-proxy-splitviews/registry.xml b/plone/app/caching/profiles/with-caching-proxy-splitviews/registry.xml index 3d32eb3..22943d7 100644 --- a/plone/app/caching/profiles/with-caching-proxy-splitviews/registry.xml +++ b/plone/app/caching/profiles/with-caching-proxy-splitviews/registry.xml @@ -21,6 +21,7 @@ userLanguage skin locked + resourceRegistries @@ -48,6 +49,7 @@ skin locked copy + resourceRegistries @@ -117,4 +119,4 @@ - + \ No newline at end of file diff --git a/plone/app/caching/profiles/with-caching-proxy/registry.xml b/plone/app/caching/profiles/with-caching-proxy/registry.xml index 56c2264..0d30b49 100644 --- a/plone/app/caching/profiles/with-caching-proxy/registry.xml +++ b/plone/app/caching/profiles/with-caching-proxy/registry.xml @@ -21,6 +21,7 @@ userLanguage skin locked + resourceRegistries @@ -39,6 +40,7 @@ skin locked copy + resourceRegistries diff --git a/plone/app/caching/profiles/without-caching-proxy/registry.xml b/plone/app/caching/profiles/without-caching-proxy/registry.xml index 3569909..bdbe9b4 100644 --- a/plone/app/caching/profiles/without-caching-proxy/registry.xml +++ b/plone/app/caching/profiles/without-caching-proxy/registry.xml @@ -21,6 +21,7 @@ userLanguage skin locked + resourceRegistries @@ -39,6 +40,7 @@ skin locked copy + resourceRegistries @@ -92,4 +94,4 @@ - + \ No newline at end of file diff --git a/plone/app/caching/tests/test_profile_with_caching_proxy.py b/plone/app/caching/tests/test_profile_with_caching_proxy.py index 320371d..b3897eb 100644 --- a/plone/app/caching/tests/test_profile_with_caching_proxy.py +++ b/plone/app/caching/tests/test_profile_with_caching_proxy.py @@ -147,7 +147,7 @@ def test_composite_viewsxx(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - self.assertEqual('"|test_user_1_|%d|en|%s|0' % (catalog.getCounter( + self.assertEqual('"|test_user_1_|%d|en|%s|0|0' % (catalog.getCounter( ), skins_tool.default_skin), _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) @@ -162,7 +162,7 @@ def test_composite_viewsxx(self): browser.headers['X-Cache-Operation']) self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - self.assertEqual('"|test_user_1_|%d|en|%s|0' % (catalog.getCounter( + self.assertEqual('"|test_user_1_|%d|en|%s|0|1' % (catalog.getCounter( ), skins_tool.default_skin), _normalize_etag(browser.headers['ETag'])) # Request the authenticated page @@ -181,7 +181,7 @@ def test_composite_viewsxx(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - self.assertEqual('"|test_user_1_|%d|en|%s' % (catalog.getCounter( + self.assertEqual('"|test_user_1_|%d|en|%s|0' % (catalog.getCounter( ), skins_tool.default_skin), _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) @@ -227,7 +227,7 @@ def test_composite_viewsxx(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - self.assertEqual('"||%d|en|%s|0' % (catalog.getCounter( + self.assertEqual('"||%d|en|%s|0|0' % (catalog.getCounter( ), skins_tool.default_skin), _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) @@ -244,7 +244,7 @@ def test_composite_viewsxx(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - self.assertEqual('"||%d|en|%s' % (catalog.getCounter( + self.assertEqual('"||%d|en|%s|0' % (catalog.getCounter( ), skins_tool.default_skin), _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) @@ -264,7 +264,7 @@ def test_composite_viewsxx(self): self.assertIn(testText, browser.contents) self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - self.assertEqual('"||%d|en|%s' % (catalog.getCounter( + self.assertEqual('"||%d|en|%s|0' % (catalog.getCounter( ), skins_tool.default_skin), _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) diff --git a/plone/app/caching/tests/test_profile_without_caching_proxy.py b/plone/app/caching/tests/test_profile_without_caching_proxy.py index d19db4e..0692758 100644 --- a/plone/app/caching/tests/test_profile_without_caching_proxy.py +++ b/plone/app/caching/tests/test_profile_without_caching_proxy.py @@ -135,7 +135,7 @@ def test_composite_views(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - tag = '"|test_user_1_|{0}|en|{1}|0'.format( + tag = '"|test_user_1_|{0}|en|{1}|0|0'.format( catalog.getCounter(), default_skin, ) @@ -153,7 +153,7 @@ def test_composite_views(self): browser.headers['X-Cache-Operation']) self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - tag = '"|test_user_1_|{0}|en|{1}|0'.format( + tag = '"|test_user_1_|{0}|en|{1}|0|1'.format( catalog.getCounter(), default_skin, ) @@ -175,7 +175,7 @@ def test_composite_views(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - tag = '"|test_user_1_|{0}|en|{1}'.format( + tag = '"|test_user_1_|{0}|en|{1}|0'.format( catalog.getCounter(), default_skin, ) @@ -223,7 +223,7 @@ def test_composite_views(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - tag = '"||{0}|en|{1}|0'.format(catalog.getCounter(), default_skin) + tag = '"||{0}|en|{1}|0|0'.format(catalog.getCounter(), default_skin) self.assertEqual(tag, _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) @@ -240,7 +240,7 @@ def test_composite_views(self): # This should use cacheInBrowser self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - tag = '"||{0}|en|{1}'.format(catalog.getCounter(), default_skin) + tag = '"||{0}|en|{1}|0'.format(catalog.getCounter(), default_skin) self.assertEqual(tag, _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires'])) @@ -260,7 +260,7 @@ def test_composite_views(self): self.assertIn(testText, browser.contents) self.assertEqual('max-age=0, must-revalidate, private', browser.headers['Cache-Control']) - tag = '"||{0}|en|{1}'.format(catalog.getCounter(), default_skin) + tag = '"||{0}|en|{1}|0'.format(catalog.getCounter(), default_skin) self.assertEqual(tag, _normalize_etag(browser.headers['ETag'])) self.assertGreater(now, dateutil.parser.parse( browser.headers['Expires']))