Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
5e15952a
Commit
5e15952a
authored
Dec 11, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
1bbd6215
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
20 additions
and
12 deletions
+20
-12
zloadrace.py
zloadrace.py
+20
-12
No files found.
zloadrace.py
View file @
5e15952a
...
...
@@ -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
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment