Commit af381382 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent bb8587da
......@@ -166,7 +166,7 @@ error _Conn::_pinner(context::Context ctx) {
// mark the connection non-operational if the pinner fails
wconn._downMu.lock();
if (wconn._downErr == nil) {
wconn._downErr = fmt::errorf("no longer operational due to: %s", v(err));
wconn._downErr = fmt::errorf("no longer operational due to: %w", err);
// XXX make all fileh and mapping invalid.
}
wconn._downMu.unlock();
......
......@@ -4,7 +4,6 @@
from __future__ import print_function
from ZODB import DB
from ZODB.MappingStorage import MappingStorage
from ZODB.POSException import ConflictError
import transaction
from persistent import Persistent
......@@ -24,20 +23,6 @@ from wendelin.lib.testing import TestDB_ZEO
@func
def main():
"""
if 0:
zstor = MappingStorage()
db = DB(zstor)
else:
tdb = TestDB_ZEO('<zeo>')
tdb.setup()
defer(tdb.teardown)
zstor = tdb.getZODBStorage()
db = DB(zstor)
#zstor.app.poll_thread.name = 'C.poll'
"""
tdb = TestDB_ZEO('<zeo>')
tdb.setup()
defer(tdb.teardown)
......@@ -47,7 +32,6 @@ def main():
db = DB(zstor)
return db
# init initializes the database with two integer objects - obj1/obj2 that are set to 0.
@func
def init():
......@@ -65,20 +49,24 @@ def main():
zconn.close()
# T1 accesses obj1/obj2 in a loop and verifies that obj1.i == obj2.i
# T is a worker that accesses obj1/obj2 in a loop and verifies
# `obj1.i == obj2.i` invariant.
#
# access to obj1 is organized to always trigger loading from zstor.
# access to obj2 goes through zconn cache and so verifies whether the cache is not stale.
#
# XXX + commit
# Once in a while T tries to modify obj{1,2}.i maintaining the invariant as
# test source of changes for other workers.
@func
def T1(ctx, name, N):
def T(ctx, name, N):
db = dbopen()
defer(db.close)
@func
def t1():
transaction.begin()
zconn = db.open()
defer(zconn.close)
root = zconn.root()
obj1 = root['obj1']
......@@ -92,7 +80,7 @@ def main():
i1 = obj1.i
i2 = obj2.i
if i1 != i2:
print('FAIL')
#print('FAIL')
raise AssertionError("T%s: obj1.i (%d) != obj2.i (%d)" % (name, i1, i2))
# change objects once in a while
......@@ -101,64 +89,27 @@ def main():
obj1.i += 1
obj2.i += 1
#transaction.abort() # we did not changed anything; also fails with commit
try:
transaction.commit()
except ConflictError:
#print('conflict -> ignore')
transaction.abort()
zconn.close()
for i in range(N):
if ready(ctx.done()):
break
#print('T%s.%d' % (name, i))
t1()
raise RuntimeError("T1: done")
"""
# T2 changes obj1/obj2 in a loop by doing `objX.i += 1`.
#
# Since both objects start from 0, the invariant that `obj1.i == obj2.i` is always preserved.
@func
def T2(ctx, N):
db = dbopen()
defer(db.close)
def t2():
transaction.begin()
zconn = db.open()
root = zconn.root()
obj1 = root['obj1']
obj2 = root['obj2']
obj1.i += 1
obj2.i += 1
assert obj1.i == obj2.i
transaction.commit()
zconn.close()
for i in range(N):
if ready(ctx.done()):
break
#print('T2.%d' % i)
t2()
"""
# run T1 and T2 concurrently. As of 20191210, due to race condition in
# Connection.open, it triggers the bug where T1 sees stale obj2 with obj1.i != obj2.i
# run 8 T workers concurrently. As of 20200123, likely due to race conditions
# in ZEO, it triggers the bug where T sees stale obj2 with obj1.i != obj2.i
init()
N = 100000
wg = sync.WorkGroup(context.background())
for x in 'abcdefgh':
wg.go(T1, x, N)
#wg.go(T2, N)
for x in range(8):
wg.go(T, x, N)
wg.wait()
print('OK')
......
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