Commit d8fe835f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent dcfde02d
#!/usr/bin/env python
"""XXX
"""
from __future__ import print_function
from ZODB import DB
from ZODB.MappingStorage import MappingStorage
import transaction
from persistent import Persistent
from golang import sync, context
# PInt is persistent integer.
class PInt(Persistent):
def __init__(self, i):
self.i = i
def main():
zstor = MappingStorage()
db = DB(zstor)
# init initializes the database with two integer objects - obj1/obj2 that are set to 0.
def init():
transaction.begin()
zconn = db.open()
root = zconn.root()
root['obj1'] = PInt(0)
root['obj2'] = PInt(0)
transaction.commit()
zconn.close()
# T1 accesses obj1/obj2 in a loop and verifies that obj1.i == obj2.i
#
# 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.
def T1(ctx, N):
def t1():
transaction.begin()
zconn = db.open()
root = zconn.root()
obj1 = root['obj1']
obj2 = root['obj2']
# obj1 - reload it from zstor
# obj2 - get it from zconn cache
obj1._p_invalidate()
# both objects must have the same values
i1 = obj1.i
i2 = obj2.i
if i1 != i2:
raise AssertionError("T1: obj1.i (%d) != obj2.i (%d)" % (i1, i2))
transaction.abort() # we did not changed anything; also fails with commit
zconn.close()
for i in range(N):
#print('T1.%d' % i)
t1()
# 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.
def T2(ctx, N):
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):
#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
init()
N = 1000
wg = sync.WorkGroup(context.background())
wg.go(T1, N)
wg.go(T2, N)
wg.wait()
if __name__ == '__main__':
main()
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