-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2nd level caching for zcatalog by means of plone.memoize #17
base: master
Are you sure you want to change the base?
Conversation
f2e57ee
to
6ee6f37
Compare
@hannosch I have rebased the PR to master branch and added some tests for caching support. I believe that the caching mechanism now works reliably. |
6ee6f37
to
5ce1295
Compare
b7aae3a
to
3394317
Compare
What is the status of this PR? Is it ready to merge? |
From my point of view, the pull request is ready to be merged. |
The worst problem we have in our environment is that ZODB cannot properly maintain its cache size (set via |
BTW: A separate mount point for the ZCatalog (e.g. portal_catalog in Plone) with individual cache sizes can also improve the cache management and performance of ZODB. This eliminates competing database accesses with different purposes. |
Thanks for the advice, that can be useful for large ZCatalogs. I was wrong about memory usage in |
Another concern was transaction isolation. The code prevents possible race scenarios by mixing index counters into the cache key. |
You are not bound to zope.ramcache's default settings. plone.memoize.ram uses a utility for cache choosing. Default settings can easily be changed or extended by providing an own utility. In addition, you can use other caching storages (e.g. memcached, https://docs.plone.org/external/plone.app.caching/docs/ram-cache.html). I can use additionally the _p_serial (transaction id) of the index counter objects for the cache key generation. Ambiguities of result sets should then be excluded. |
dc9b564
to
9d8aea6
Compare
ZCatalog's cache key consider now the transaction ids of the index counter. This makes the cache key unique and thread aware. Ambiguities of result sets should be solved by the conflict error handling. |
That might work not that well: the
So it is quite possible that two concurrent transaction that started to work with the same index object would see the same |
Thank you for the info. Currently I am experimenting with a transactional aware CacheAdapter that implements the IDataManager interface. It would be great if there was an adequate test scenario. |
Here is a gist that works in the stock ZCatalog and fails under the cached implementation due to inconsistent cache read (tested on commit 9d8aea6). The race scenario is:
The gist contains a conflict retry mechanism similar to ZPublisher. That was mostly done to handle |
One annoying comment on the PR: Unfortunately plone.memoize is licensed under the GPL only. So it can't be used here, as the code is under the ZPL. We can use zope.ramcache directly or store things again on the request object if so desired. |
OK, I chose plone.memoize because it is easy to use RAMCache by default or e.g. memcache for large sites with many Zope workers. For better transaction management, I am currently working on a solution that implements IDataManager. Perhaps this is the best time to program an own cache utility for the ZCatalog.
|
@andbag, you are welcome, but that was just a single race scenario out of many others possible. Using transaction-aware cache is also not a guarantee per se. For example, One possible approach could be storing cache in the |
Okay, I understand. While I focused on data consistency, you want to guarantee data isolation during a transaction. Of course I know the'v' attribute, but it should not be the only cache solution. Our university runs a very large Plone site with many workers who could benefit from a shared cache. |
@icemac, yes, you're right. In addition to the licensing issue, we need to clarify whether the current cache implementation preserves data consistency and isolation during a transaction. |
@hannosch, I'm a little frustrated that the wheel has to be invented a second time for caching. You are also a maintainer of plone.memoize. Isn't it possible to publish plone.memoize under dual licence model? |
@andbag I think relicensing of a Plone package has to be decided by one of the teams of the Plone foundation (but I am not sure which team). There were some packages in the past which got a new license on demand for something which is not GPL. (but I do not remember which packages where the ones.) I'd suggest to ask on https://community.plone.org. |
The licensing question is waiting for an answer from the Plone Community (s. https://community.plone.org/t/re-licensing-plone-memoize-to-support-products-zcatalog/7034) |
Writing here, as not sure everybody follows community.plone.org. Normally, a license change to a Plone package would be requested by the Framework team, and then the Board of the Plone Foundation decides. So that's the easiest way. It would definitely also help to hear @hannosch on it, as he's a/the principal author. And to know what's the plan. From what I gather, it is not to literally take code from plone.memoize into the zopefoundation org repo, but just to depend on it. That could be accomplished by making plone.memoize available as LGPL, which is a much smaller ask, and you can probably just write directly to the Board ([email protected]) but I'm not 100% sure on that, as the technical details of this PR are slightly above my head. Re-licensing as ZPL would be a bigger ask, we then would prefer to relicense as MIT to keep our licensing zoo down. (Since it's the preferred license of the JavaScript world there's already quite some MIT code in the Plonefoundation repos). It's possible to do, if you want to copy actual code into the Zopefoundation repo, but at least it would need consent of @hannosch , and some indication by the Plone Framework team that this couldn't inadvertently harm Plone. (oh, and I'm on the Plone Board as president, which is why I'm commenting...) |
Here's the licensing policy: Many plone.* components have been relicensed. The modified BSD is entirely compatible with the ZPL. |
Interesting! While the documentation at plone.org says that plone.memoize was supposedly re-licensed under BSD in Sep 2010, the current code in the repo of plone.memoize is licensed under the GPL. Currently the PR depends only on plone.memoize (re-licensing to LGPL or BSD (?) seems to be sufficient). However, it is a design question whether the cache is shared with other plone/zope modules or whether the ZCatalog has its own cache logic. At the moment I see no reason why one should prefer to separate the cache logic. What is your (especially @hannosch) opinion? |
The plot thickens ;-) But probably never actually implemented as a pull request on plone.memoize. |
isn't an adequate marker for an unique key generation This reverts commit 9d8aea6.
8eb64f2
to
ed38d23
Compare
@hannosch I have now implemented a prototype for the caching of the catalog resultset based on plone.memoize. The cache key generation is based on the combination of the per-index counters. In addition, I have upgraded all PluginIndexes to support the getCounter logic (new interface IIndexCounter added). It's currently only a proof of concept and therefore, the caching tests are missing. Can you please do the code review?