Commit 1c876254 authored by Grégory Wisniewski's avatar Grégory Wisniewski

Don't process queued lock requests related to an aborted transaction.

When a delayed store is processed, don't take the lock if the transaction
is no more registered (may have been aborted due to a timeout with the
delayed store).
Change the TransactionManager API: add register() that must be called before
any storeObject/storeTransaction operation.

git-svn-id: https://svn.erp5.org/repos/neo/trunk@2159 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent 25b66510
......@@ -43,16 +43,23 @@ class ClientOperationHandler(BaseClientAndStorageOperationHandler):
def askStoreTransaction(self, conn, tid, user, desc,
ext, oid_list):
uuid = conn.getUUID()
self.app.tm.storeTransaction(uuid, tid, oid_list, user, desc, ext,
self.app.tm.register(conn.getUUID(), tid)
self.app.tm.storeTransaction(tid, oid_list, user, desc, ext,
False)
conn.answer(Packets.AnswerStoreTransaction(tid))
def _askStoreObject(self, conn, oid, serial, compression, checksum, data,
tid, request_time):
uuid = conn.getUUID()
if tid not in self.app.tm:
# transaction was aborted, cancel this event
logging.info('Forget store of %s:%s by %s delayed by %s',
dump(oid), dump(serial), dump(tid),
dump(self.app.tm.getLockingTID(oid)))
# send an answer as the client side is waiting for it
conn.answer(Packets.AnswerStoreObject(0, oid, serial))
return
try:
self.app.tm.storeObject(uuid, tid, serial, oid, compression,
self.app.tm.storeObject(tid, serial, oid, compression,
checksum, data, None)
except ConflictError, err:
# resolvable or not
......@@ -71,6 +78,8 @@ class ClientOperationHandler(BaseClientAndStorageOperationHandler):
def askStoreObject(self, conn, oid, serial,
compression, checksum, data, tid):
# register the transaction
self.app.tm.register(conn.getUUID(), tid)
self._askStoreObject(conn, oid, serial, compression, checksum, data,
tid, time.time())
......
......@@ -123,9 +123,9 @@ class TransactionManager(object):
"""
return tid in self._transaction_dict
def _getTransaction(self, tid, uuid):
def register(self, uuid, tid):
"""
Get or create the transaction object for this tid
Register a transaction, it may be already registered
"""
transaction = self._transaction_dict.get(tid, None)
if transaction is None:
......@@ -193,17 +193,18 @@ class TransactionManager(object):
self._loid = self._loid_seen
self._app.dm.setLastOID(self._loid)
def storeTransaction(self, uuid, tid, oid_list, user, desc, ext, packed):
def storeTransaction(self, tid, oid_list, user, desc, ext, packed):
"""
Store transaction information received from client node
"""
transaction = self._getTransaction(tid, uuid)
assert tid in self, "Transaction not registered"
transaction = self._transaction_dict[tid]
transaction.prepare(oid_list, user, desc, ext, packed)
def getLockingTID(self, oid):
return self._store_lock_dict.get(oid)
def storeObject(self, uuid, tid, serial, oid, compression, checksum, data,
def storeObject(self, tid, serial, oid, compression, checksum, data,
value_serial):
"""
Store an object received from client node
......@@ -235,7 +236,8 @@ class TransactionManager(object):
raise ConflictError(locking_tid)
# store object
transaction = self._getTransaction(tid, uuid)
assert tid in self, "Transaction not registered"
transaction = self._transaction_dict[tid]
transaction.addObject(oid, compression, checksum, data, value_serial)
# update loid
......
......@@ -44,7 +44,7 @@ class StorageClientHandlerTests(NeoTestBase):
self.app.store_lock_dict = {}
self.app.load_lock_dict = {}
self.app.event_queue = deque()
self.app.tm = Mock()
self.app.tm = Mock({'__contains__': True})
# handler
self.operation = ClientOperationHandler(self.app)
# set pmn
......@@ -211,7 +211,7 @@ class StorageClientHandlerTests(NeoTestBase):
oid, serial, comp, checksum, data = self._getObject()
self.operation.askStoreObject(conn, oid, serial, comp, checksum,
data, tid)
self._checkStoreObjectCalled(uuid, tid, serial, oid, comp,
self._checkStoreObjectCalled(tid, serial, oid, comp,
checksum, data, None)
self.checkAnswerStoreObject(conn)
......
This diff is collapsed.
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