Fix loadBefore vs GC
TemporaryStorage uses ._index {} oid -> serial ._opickle {} oid -> data as data store for load. However for loadBefore ._conflict_cache {} (oid,serial) -> (data, time) is reused as data store. That would be ok if that place would be treated as data store, but given its primary purpose - as its name suggests - was originally to be a cache to resolve conflicts, it is "logical" that entries in this cache are garbage-collected when entry age becomes > gc threshold. Only now there is a problem: if an object is committed once, and time passes, corresponding entry in ._conflict_cache will be removed. And this would manifest itself as - load(oid) -> gives latest data for the object (obtained via ._index and ._opickle) but - loadBefore(oid, @head) -> gives POSKeyError -> Fix it by always preserving latest object revision in ._conflict_cache from being removed on GC. The fix is important for systems that use ZODB5, or ZODB4-wc2[1] because there ZODB.Connection switched from primarily using load to exclusively using loadBefore. /cc @icemac @mauritsvanrees @mgedmin @d-maurer @dwt @hannosch Fixes: https://github.com/zopefoundation/tempstorage/issues/8 [1] nexedi/ZODB@8e7eab33
Showing