-
Notifications
You must be signed in to change notification settings - Fork 19
[WIP] pack: Clear all non-current entries after pack #162
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -559,7 +559,16 @@ def pack(self, t=None, referencesf=None, wait=1, days=0): | |
if t is None: | ||
t = time.time() | ||
t = t - (days * 86400) | ||
return self._call('pack', t, wait) | ||
ret = self._call('pack', t, wait) | ||
# remove all non-current entries from the cache. | ||
# This way we make sure that loadBefore with before < packtime, won't | ||
# return data from the cache, instead of returning "no data" if requested object | ||
# has current revision >= packtime. | ||
# By clearing all noncurrent entries we might remove more data from the | ||
# cache than is strictly necessary, but since access to noncurrent data | ||
# is seldom, that should not cause problems in practice. | ||
self._cache.clearAllNonCurrent() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally, I would like to see a specific direct test case for this. While I know that there was a generic ZODB test failure, it's not obvious that this is the fix for it. What I mean is, the symptom (a failure to raise a particular exception) and the fix (making sure there are no non-current items in the cache) aren't necessarily clearly linked. I could imagine that a slight refactoring of the ZODB test that introduces additional clients or changes the timing or whatever might let it pass without this line of code being present. I would suggest that a direct test for this would (a) establish non-current items in the cache and verify their existence in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, especially in the light of the bug you point out that the cache is not invalidated on other clients. |
||
return ret | ||
|
||
def store(self, oid, serial, data, version, txn): | ||
"""Storage API: store data for an object.""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -253,6 +253,34 @@ def test_clear_zeo_cache(self): | |
self.assertEqual(cache.load(n3), None) | ||
self.assertEqual(cache.loadBefore(n3, n2), None) | ||
|
||
def testClearAllNonCurrent(self): | ||
cache = self.cache | ||
cache.store(p64(1), n1, n2, b'1@1') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One space following a comma, please. Please don't introduce extra horizontal whitespace for the purposes of vertical alignment. It's very fiddly and leads to unnecessary multi-line changes in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. argh, ok. Even though personally I adhere to the oppsite, let's not argue on this and correct it here to be without vertical alignment. For the reference |
||
cache.store(p64(1), n2, n3, b'1@2') | ||
cache.store(p64(1), n3, None, b'1') | ||
cache.store(p64(2), n2, n3, b'2@2') | ||
cache.store(p64(2), n3, None, b'2') | ||
|
||
eq = self.assertEqual | ||
eq(len(cache), 5) | ||
eq(cache.load(p64(1)), (b'1', n3)) | ||
eq(cache.loadBefore(p64(1), n3), (b'1@2', n2, n3)) | ||
eq(cache.loadBefore(p64(1), n2), (b'1@1', n1, n2)) | ||
eq(cache.loadBefore(p64(1), n1), None) | ||
eq(cache.load(p64(2)), (b'2', n3)) | ||
eq(cache.loadBefore(p64(2), n3), (b'2@2', n2, n3)) | ||
eq(cache.loadBefore(p64(2), n2), None) | ||
|
||
cache.clearAllNonCurrent() | ||
eq(len(cache), 2) | ||
eq(cache.load(p64(1)), (b'1', n3)) | ||
eq(cache.loadBefore(p64(1), n3), None) | ||
eq(cache.loadBefore(p64(1), n2), None) | ||
eq(cache.loadBefore(p64(1), n1), None) | ||
eq(cache.load(p64(2)), (b'2', n3)) | ||
eq(cache.loadBefore(p64(2), n3), None) | ||
eq(cache.loadBefore(p64(2), n2), None) | ||
|
||
def testChangingCacheSize(self): | ||
# start with a small cache | ||
data = b'x' | ||
|
Uh oh!
There was an error while loading. Please reload this page.