Skip to content

Commit

Permalink
Update the resourceRegistries ETag to use the config registry modific…
Browse files Browse the repository at this point in the history
…ation time.

This time is set since Plone 6.0.4.
Fixes #93.

This removes the previous code which read `timestamp.txt` from `/portal_resources/resource_overrides/production`.
This timestamp is no longer set in Plone 6, and does not influence anything.
  • Loading branch information
mauritsvanrees committed Apr 25, 2023
1 parent 64d39ba commit 57e7947
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 49 deletions.
4 changes: 4 additions & 0 deletions news/93.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Update the resourceRegistries ETag to use the config registry modification time.
This time is set since Plone 6.0.4.
Fixes `issue 93 <https://github.com/plone/plone.app.caching/issues/93>`_.
[maurits]
29 changes: 14 additions & 15 deletions plone/app/caching/operations/etags.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
from plone.app.caching.operations.utils import getContext
from plone.app.caching.operations.utils import getLastModifiedAnnotation
from plone.base.utils import safe_hasattr
from plone.registry.interfaces import IRegistry
from Products.CMFCore.interfaces import ICatalogTool
from Products.CMFCore.interfaces import IMembershipTool
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.resources.utils import get_override_directory
from Products.CMFPlone.resources.utils import PRODUCTION_RESOURCE_DIRECTORY
from zope.component import adapter
from zope.component import queryMultiAdapter
from zope.component import queryUtility
Expand All @@ -19,6 +18,13 @@
import time


try:
# available since Plone 6.0.4
from Products.CMFPlone.resources.browser.resource import _RESOURCE_REGISTRY_MTIME
except ImportError:
_RESOURCE_REGISTRY_MTIME = None


@implementer(IETagValue)
@adapter(Interface, Interface)
class UserID:
Expand Down Expand Up @@ -239,22 +245,15 @@ def __init__(self, published, request):
self.request = request

def __call__(self):
context = getContext(self.published)
container = get_override_directory(context)
if PRODUCTION_RESOURCE_DIRECTORY not in container:
if _RESOURCE_REGISTRY_MTIME is None:
return ""
production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
filename = "timestamp.txt"
if filename not in production_folder:
registry = queryUtility(IRegistry)
if registry is None:
return ""
timestamp = production_folder.readFile(filename)
if not timestamp:
mtime = getattr(registry, _RESOURCE_REGISTRY_MTIME, None)
if mtime is None:
return ""
# timestamp is in bytes, and we must return a string.
# On Python 2 this is the same, but not on Python 3.
if not isinstance(timestamp, str):
timestamp = timestamp.decode("utf-8")
return timestamp
return str(mtime)


@implementer(IETagValue)
Expand Down
50 changes: 22 additions & 28 deletions plone/app/caching/tests/test_profile_with_caching_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ def test_composite_viewsxx(self):
# Can we just call that test from this context?

catalog = self.portal["portal_catalog"]
skins_tool = self.portal["portal_skins"]
default_skin = self.portal["portal_skins"].default_skin

# Add folder content
setRoles(self.portal, TEST_USER_ID, ("Manager",))
self.portal.invokeFactory("Folder", "f1")
self.portal["f1"].title = "one"
self.portal["f1"].title = "Folder one"
self.portal["f1"].description = "Folder one description"
self.portal["f1"].reindexObject()

Expand All @@ -105,9 +105,16 @@ def test_composite_viewsxx(self):
# - turn on gzip?
# - set skin? Maybe
# - leave status unlocked
#
# - set the mod date on the resource registries? Probably.
transaction.commit()

# Since Plone 6.0.4 we have a modification date on the registry.
from Products.CMFPlone.resources.browser.resource import (
_RESOURCE_REGISTRY_MTIME,
)

mtime = str(getattr(self.registry, _RESOURCE_REGISTRY_MTIME))

# Request the authenticated folder
now = stable_now()
browser = Browser(self.app)
Expand All @@ -124,10 +131,8 @@ def test_composite_viewsxx(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
self.assertEqual(
f'"|test_user_1_|{catalog.getCounter()}|en|{skins_tool.default_skin}|0|0|"',
normalize_etag(browser.headers["ETag"]),
)
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

# Set the copy/cut cookie and then request the folder view again
Expand All @@ -141,10 +146,8 @@ def test_composite_viewsxx(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
self.assertEqual(
f'"|test_user_1_|{catalog.getCounter()}|en|{skins_tool.default_skin}|0|1|"',
normalize_etag(browser.headers["ETag"]),
)
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|1|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))

# Request the authenticated page
now = stable_now()
Expand All @@ -163,10 +166,8 @@ def test_composite_viewsxx(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
self.assertEqual(
f'"|test_user_1_|{catalog.getCounter()}|en|{skins_tool.default_skin}|0|"',
normalize_etag(browser.headers["ETag"]),
)
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

# Request the authenticated page again -- to test RAM cache.
Expand Down Expand Up @@ -205,7 +206,6 @@ def test_composite_viewsxx(self):
# Request the anonymous folder
now = stable_now()
browser = Browser(self.app)
browser.handleErrors = False
browser.open(self.portal["f1"].absolute_url())
self.assertEqual("plone.content.folderView", browser.headers["X-Cache-Rule"])
self.assertEqual(
Expand All @@ -215,10 +215,8 @@ def test_composite_viewsxx(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
self.assertEqual(
f'"||{catalog.getCounter()}|en|{skins_tool.default_skin}|0|0|"',
normalize_etag(browser.headers["ETag"]),
)
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

# Request the anonymous page
Expand All @@ -234,10 +232,8 @@ def test_composite_viewsxx(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
self.assertEqual(
f'"||{catalog.getCounter()}|en|{skins_tool.default_skin}|0|"',
normalize_etag(browser.headers["ETag"]),
)
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

# Request the anonymous page again -- to test RAM cache.
Expand All @@ -257,10 +253,8 @@ def test_composite_viewsxx(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
self.assertEqual(
f'"||{catalog.getCounter()}|en|{skins_tool.default_skin}|0|"',
normalize_etag(browser.headers["ETag"]),
)
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

# Request the anonymous page again -- with an INM header to test 304.
Expand Down
19 changes: 13 additions & 6 deletions plone/app/caching/tests/test_profile_without_caching_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ def test_composite_views(self):
# - set the mod date on the resource registries? Probably.
transaction.commit()

# Since Plone 6.0.4 we have a modification date on the registry.
from Products.CMFPlone.resources.browser.resource import (
_RESOURCE_REGISTRY_MTIME,
)

mtime = str(getattr(self.registry, _RESOURCE_REGISTRY_MTIME))

# Request the authenticated folder
now = stable_now()
browser = Browser(self.app)
Expand All @@ -108,7 +115,7 @@ def test_composite_views(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|0|"'
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

Expand All @@ -123,7 +130,7 @@ def test_composite_views(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|1|"'
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|1|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))

# Request the authenticated page
Expand All @@ -143,7 +150,7 @@ def test_composite_views(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|"'
tag = f'"|test_user_1_|{catalog.getCounter()}|en|{default_skin}|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

Expand Down Expand Up @@ -192,7 +199,7 @@ def test_composite_views(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|0|"'
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

Expand All @@ -209,7 +216,7 @@ def test_composite_views(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|"'
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

Expand All @@ -230,7 +237,7 @@ def test_composite_views(self):
self.assertEqual(
"max-age=0, must-revalidate, private", browser.headers["Cache-Control"]
)
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|"'
tag = f'"||{catalog.getCounter()}|en|{default_skin}|0|{mtime}"'
self.assertEqual(tag, normalize_etag(browser.headers["ETag"]))
self.assertGreater(now, dateutil.parser.parse(browser.headers["Expires"]))

Expand Down

0 comments on commit 57e7947

Please sign in to comment.