Closed azmeuk closed 5 years ago
_p_mtime
is just a wrapper (which loses precision, by the way) around _p_serial
. In ZODB, _p_serial
is the transaction ID, and transaction IDs always increase; they can never go backwards. When you create the DB, ZODB creates the first transaction to initially create the root object, and thus establishes the baseline for all transaction IDs going forward.
>>> db = ZODB.DB(None)
>>> db._storage.lastTransaction()
b'\x03\xd1\xffFF\xd1+\x00'
>>> db.open().root()._p_serial
b'\x03\xd1\xffFF\xd1+\x00'
When it's time to commit, ZODB essentially says to the TimeStamp
class, "give me a TimeStamp based on the current time that's later than the last one I committed." If the clock has gone backwards, it'll be ignored.
@jamadden Thank you for your excellent explanation. @azmeuk Does this explanation answer your question so the issue can be closed?
All "p*" attributes are special. When I remember right,
then _p_mtime
is just a different represantation of _p_serial
.
The latter contains the transaction id, the transaction id which caused
the current object state. Transaction ids are mostly timestamps. However,
the ZODB enforces that they strictly increase. This means you cannot
fake arbitrary times in the past.
@jamadden Thank you. Your answer helped me a lot understand what is going on. @icemac Yep!
python-libfaketime is a great python wrapper for libfaketime. It catches system-calls related to date and time, and allows you to mock them as you want:
The code of python-libfaketime is outrageously short and simple (< 300 LOC), and for what I have played with, it works great in many contexts, including C extensions. However, I encountered an unexpected behavior with ZODB and the persistent
_p_mtime
attribute.If a ZODB database object is created in a libfaketime context, after editing some persistent objects,
_p_mtime
value is the mocked time, as expected:But if the ZODB database object is created outside the libfaketime context,
_p_mtime
value is not mocked:I would have expected the latter example to print a mocked time since the modification and the commit are done in the libfaketime context.
So I know that bug report related to different libraries that were not designed to work together are sometimes tricky, but I though someone here might have a clue.
ZODB.DB
creation that would need to happen in a libfaketime context?Thank you for your help