Commit 2120a7a2 authored by Julien Muchembled's avatar Julien Muchembled Committed by Kirill Smelkov

[ZODB3] Allow serial to be returned as late as tpc_finish

----

kirr: This is likely to be ZODB3-backport of https://github.com/zopefoundation/ZODB/pull/69
Taken from https://lab.nexedi.com/nexedi/neoppod/blob/v1.12-52-gfb746e6b/ZODB3.patch
parent d9d5b50a
......@@ -776,6 +776,10 @@ class IStorage(Interface):
called while the storage transaction lock is held. It takes
the new transaction id generated by the transaction.
The return value can be either None or a serial giving new
serial for objects whose ids were passed to previous store calls
in the same transaction, and for which no serial was returned
from either store or tpc_vote for objects passed to store.
"""
def tpc_vote(transaction):
......@@ -794,8 +798,6 @@ class IStorage(Interface):
The return value can be either None or a sequence of object-id
and serial pairs giving new serials for objects who's ids were
passed to previous store calls in the same transaction.
After the tpc_vote call, new serials must have been returned,
either from tpc_vote or store for objects passed to store.
A serial returned in a sequence of oid/serial pairs, may be
the special value ZODB.ConflictResolution.ResolvedSerial to
......
......@@ -72,8 +72,10 @@ class BasicStorage:
r1 = self._storage.store(oid, None, zodb_pickle(MinPO(11)),
'', txn)
r2 = self._storage.tpc_vote(txn)
self._storage.tpc_finish(txn)
serial = self._storage.tpc_finish(txn)
newrevid = handle_serials(oid, r1, r2)
if newrevid is None and serial is not None:
newrevid = serial
data, revid = self._storage.load(oid, '')
value = zodb_unpickle(data)
eq(value, MinPO(11))
......
......@@ -155,10 +155,12 @@ class StorageClientThread(TestThread):
r2 = self.storage.tpc_vote(t)
self.pause()
self.storage.tpc_finish(t)
serial = self.storage.tpc_finish(t)
self.pause()
revid = handle_serials(oid, r1, r2)
if serial is not None and revid is None:
revid = serial
self.oids[oid] = revid
class ExtStorageClientThread(StorageClientThread):
......
......@@ -150,10 +150,12 @@ class RevisionStorage:
# Finish the transaction
r2 = self._storage.tpc_vote(t)
newrevid = handle_serials(oid, r1, r2)
self._storage.tpc_finish(t)
serial = self._storage.tpc_finish(t)
except:
self._storage.tpc_abort(t)
raise
if serial is not None and newrevid is None:
newrevid = serial
return newrevid
revid1 = helper(1, None, 1)
revid2 = helper(2, revid1, 2)
......
......@@ -134,7 +134,7 @@ def handle_serials(oid, *args):
A helper for function _handle_all_serials().
"""
return handle_all_serials(oid, *args)[oid]
return handle_all_serials(oid, *args).get(oid)
def import_helper(name):
__import__(name)
......@@ -191,7 +191,9 @@ class StorageTestBase(ZODB.tests.util.TestCase):
# Finish the transaction
r2 = self._storage.tpc_vote(t)
revid = handle_serials(oid, r1, r2)
self._storage.tpc_finish(t)
serial = self._storage.tpc_finish(t)
if serial is not None and revid is None:
revid = serial
except:
self._storage.tpc_abort(t)
raise
......@@ -211,8 +213,8 @@ class StorageTestBase(ZODB.tests.util.TestCase):
self._storage.tpc_begin(t)
undo_result = self._storage.undo(tid, t)
vote_result = self._storage.tpc_vote(t)
self._storage.tpc_finish(t)
if expected_oids is not None:
serial = self._storage.tpc_finish(t)
if expected_oids is not None and serial is None:
oids = undo_result and undo_result[1] or []
oids.extend(oid for (oid, _) in vote_result or ())
self.assertEqual(len(oids), len(expected_oids), repr(oids))
......
......@@ -76,6 +76,12 @@ class TransactionalUndoStorage:
def _transaction_newserial(self, oid):
return self.__serials[oid]
def _transaction_finish(self, t, oid_list):
tid = self._storage.tpc_finish(t)
if tid is not None:
for oid in oid_list:
self.__serials[oid] = tid
def _multi_obj_transaction(self, objs):
newrevs = {}
t = Transaction()
......@@ -85,7 +91,7 @@ class TransactionalUndoStorage:
self._transaction_store(oid, rev, data, '', t)
newrevs[oid] = None
self._transaction_vote(t)
self._storage.tpc_finish(t)
self._transaction_finish(t, [x[0] for x in objs])
for oid in newrevs.keys():
newrevs[oid] = self._transaction_newserial(oid)
return newrevs
......@@ -218,9 +224,9 @@ class TransactionalUndoStorage:
self._transaction_store(oid2, revid2, p51, '', t)
# Finish the transaction
self._transaction_vote(t)
self._transaction_finish(t, [oid1, oid2])
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
self._storage.tpc_finish(t)
eq(revid1, revid2)
# Update those same two objects
t = Transaction()
......@@ -230,9 +236,9 @@ class TransactionalUndoStorage:
self._transaction_store(oid2, revid2, p52, '', t)
# Finish the transaction
self._transaction_vote(t)
self._transaction_finish(t, [oid1, oid2])
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
self._storage.tpc_finish(t)
eq(revid1, revid2)
# Make sure the objects have the current value
data, revid1 = self._storage.load(oid1, '')
......@@ -288,11 +294,12 @@ class TransactionalUndoStorage:
tid1 = info[1]['id']
t = Transaction()
oids = self._begin_undos_vote(t, tid, tid1)
self._storage.tpc_finish(t)
serial = self._storage.tpc_finish(t)
# We get the finalization stuff called an extra time:
eq(len(oids), 4)
unless(oid1 in oids)
unless(oid2 in oids)
if serial is None:
eq(len(oids), 4)
unless(oid1 in oids)
unless(oid2 in oids)
data, revid1 = self._storage.load(oid1, '')
eq(zodb_unpickle(data), MinPO(30))
data, revid2 = self._storage.load(oid2, '')
......@@ -326,7 +333,7 @@ class TransactionalUndoStorage:
self._transaction_store(oid2, revid2, p52, '', t)
# Finish the transaction
self._transaction_vote(t)
self._storage.tpc_finish(t)
self._transaction_finish(t, [oid1, oid2])
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
eq(revid1, revid2)
......@@ -346,7 +353,7 @@ class TransactionalUndoStorage:
self._transaction_store(oid2, revid2, p53, '', t)
# Finish the transaction
self._transaction_vote(t)
self._storage.tpc_finish(t)
self._transaction_finish(t, [oid1, oid2])
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
eq(revid1, revid2)
......@@ -358,10 +365,11 @@ class TransactionalUndoStorage:
tid = info[1]['id']
t = Transaction()
oids = self._begin_undos_vote(t, tid)
self._storage.tpc_finish(t)
eq(len(oids), 1)
self.failUnless(oid1 in oids)
self.failUnless(not oid2 in oids)
serial = self._storage.tpc_finish(t)
if serial is None:
eq(len(oids), 1)
self.failUnless(oid1 in oids)
self.failUnless(not oid2 in oids)
data, revid1 = self._storage.load(oid1, '')
eq(zodb_unpickle(data), MinPO(33))
data, revid2 = self._storage.load(oid2, '')
......@@ -397,7 +405,7 @@ class TransactionalUndoStorage:
self._transaction_store(oid1, revid1, p81, '', t)
self._transaction_store(oid2, revid2, p91, '', t)
self._transaction_vote(t)
self._storage.tpc_finish(t)
self._transaction_finish(t, [oid1, oid2])
revid1 = self._transaction_newserial(oid1)
revid2 = self._transaction_newserial(oid2)
eq(revid1, revid2)
......@@ -683,9 +691,9 @@ class TransactionalUndoStorage:
tid = p64(i + 1)
eq(txn.tid, tid)
L1 = [(rec.oid, rec.tid, rec.data_txn) for rec in txn]
L2 = [(oid, revid, None) for _tid, oid, revid in orig
if _tid == tid]
L1 = {(rec.oid, rec.tid, rec.data_txn) for rec in txn}
L2 = {(oid, revid, None) for _tid, oid, revid in orig
if _tid == tid}
eq(L1, L2)
......
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