Skip to content

Commit

Permalink
Rework request caching (#95)
Browse files Browse the repository at this point in the history
* Rework request caching

* work around situations in which `REQUEST` has not been set up properly

* make flake8 happy

Co-authored-by: Michael Howitz <mh@gocept.com>
  • Loading branch information
d-maurer and Michael Howitz committed Aug 21, 2020
1 parent 919bdb1 commit 6e008db
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,13 @@ Changelog
5.2 (unreleased)
----------------

- Rework request caching to avoid stale cache results in scripts (with
an artificial request).
For details:
`#94 <https://github.com/zopefoundation/Products.ZCatalog/issues/94>`_,
`Plone 5.2 mass migration: bad search results
<https://community.plone.org/t/potential-memory-corruption-during-migration-plone-4-2-5-2/11655/11>`_

- Add new method ``searchAll`` to perform a search for all documents.

- Document ``getAllBrains`` and ``searchAll`` in the interface.
Expand Down
24 changes: 17 additions & 7 deletions src/Products/PluginIndexes/unindex.py
Expand Up @@ -13,8 +13,10 @@

from logging import getLogger
import sys
from weakref import WeakKeyDictionary

from Acquisition import (
aq_base,
aq_inner,
aq_parent,
aq_get,
Expand Down Expand Up @@ -364,15 +366,23 @@ def getRequestCache(self):

cache = None
REQUEST = aq_get(self, 'REQUEST', None)
if REQUEST is not None:
catalog = aq_parent(aq_parent(aq_inner(self)))
if hasattr(REQUEST, "get"):
cache_container = REQUEST.get("__catalog_cache__")
if cache_container is None:
# we use a `WeakKeyDictionary` (rather than the
# request directly) to avoid the type of problem
# described in
# "https://community.plone.org/t/potential-memory-corruption-during-migration-plone-4-2-5-2/11655/11"
cache_container = REQUEST["__catalog_cache__"] \
= WeakKeyDictionary()
# we use the parent (of type `Products.ZCatalog.Catalog.Catalog`)
# as key to facilitate invalidation via its method
# in the future
catalog = aq_base(aq_parent(aq_inner(self)))
if catalog is not None:
# unique catalog identifier
key = '_catalogcache_{0}_{1}'.format(
catalog.getId(), id(catalog))
cache = REQUEST.get(key, None)
cache = cache_container.get(catalog, None)
if cache is None:
cache = REQUEST[key] = RequestCache()
cache = cache_container[catalog] = RequestCache()

return cache

Expand Down

0 comments on commit 6e008db

Please sign in to comment.