Commit 5e15952a authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1bbd6215
......@@ -25,14 +25,20 @@ There is no load vs invalidation race on NEO but the protection is implicit:
- client app maintains .last_tid which is updated by poller thread upon
receiving invalidations.
- when load() is called without specifing @head (the case we are considering),
it uses .last_tid for @at with which to ask storage node.
it uses .last_tid for @at with which to ask a storage node.
- even if client.load() observes .last_tid which was updated for simultaneously
committed transaction and not yet invalidated cache the following happens:
committed transaction with not yet invalidated cache, the following happens:
* client sends AskObject packet to a storage node.
* ask _locks_ corresponding connection to the storage. XXX _not_ to master from which we should have received invalidation message !
- client.app.load
* when the answer arrives it has to be picked by client poller thread.
* the poller thread won't proceed to that packet until the function that modified .last_tid finishes
* that function (neo/client/handlers/master.py invalidateObjects()) is also
invalidating NEO cache _and_ calls ZODB.DB.invalidate()
* ZODB.DB.invalidate calls ZODB.Connection.invalidate which sets
zconn._txn_time and zconn._invalidated
* even when storage-level load completes with newer than @head serial,
ZODB.Connection.setstate checks for oid in its ._invalidated, sees its
there, and retries the load with before=._txn_time
XXX load vs invalidation race is there on ZODB4 and ZODB3, but on ZODB5 there is
......@@ -68,14 +74,8 @@ def main():
# two ZODB client storage connections to the same server
zstor1 = tdb.getZODBStorage() ; defer(zstor1.close)
zstor2 = tdb.getZODBStorage() ; defer(zstor2.close)
db1 = DB(zstor1)
db2 = DB(zstor2)
zstor1.app.poll_thread.name = 'C1.poll'
zstor2.app.poll_thread.name = 'C2.poll'
# XXX doc
def init():
......@@ -89,6 +89,14 @@ def main():
transaction.commit()
zconn.close()
init()
zstor2 = tdb.getZODBStorage() ; defer(zstor2.close)
db2 = DB(zstor2)
zstor2.app.poll_thread.name = 'C2.poll'
c2ready = chan() # c1 <- c2 "I'm ready to commit"
c2start = chan() # c1 -> c2 "go on to commit"
......@@ -176,7 +184,7 @@ def main():
init()
#init()
import time
time.sleep(2)
print()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment