From 3bb38c9649bb7728dfc6d422238911eb1dbb6cff Mon Sep 17 00:00:00 2001 From: Hendrik Buschmeier <hbuschme@uni-bielefeld.de> Date: Fri, 4 Dec 2015 17:42:55 +0100 Subject: [PATCH] ipaaca-python: modified retraction logic * Exceptions when trying to modify retracted IUs. * Removal of IU also retracts it. --- ipaacalib/python/src/ipaaca/buffer.py | 13 ++-- ipaacalib/python/src/ipaaca/iu.py | 102 +++++++++++++++----------- 2 files changed, 69 insertions(+), 46 deletions(-) diff --git a/ipaacalib/python/src/ipaaca/buffer.py b/ipaacalib/python/src/ipaaca/buffer.py index c4b75a4..ab97df6 100644 --- a/ipaacalib/python/src/ipaaca/buffer.py +++ b/ipaacalib/python/src/ipaaca/buffer.py @@ -4,7 +4,7 @@ # "Incremental Processing Architecture # for Artificial Conversational Agents". # -# Copyright (c) 2009-2014 Social Cognitive Systems Group +# Copyright (c) 2009-2015 Social Cognitive Systems Group # CITEC, Bielefeld University # # http://opensource.cit-ec.de/projects/ipaaca/ @@ -365,7 +365,7 @@ class OutputBuffer(Buffer): """An OutputBuffer that holds local IUs.""" def __init__(self, owning_component_name, channel=None, participant_config=None): - '''Create an Output Buffer. + '''Create an OutputBuffer. Keyword arguments: owning_component_name -- name of the entity that own this buffer @@ -479,6 +479,8 @@ class OutputBuffer(Buffer): raise ipaaca.exception.IUPublishedError(iu) if iu.buffer is not None: raise ipaaca.exception.IUPublishedError(iu) + if iu.retracted: + raise ipaaca.exception.IURetractedError(iu) if iu.access_mode != ipaaca.iu.IUAccessMode.MESSAGE: # Messages are not really stored in the OutputBuffer self._iu_store[iu.uid] = iu @@ -486,12 +488,12 @@ class OutputBuffer(Buffer): self._publish_iu(iu) def remove(self, iu=None, iu_uid=None): - '''Remove the iu or an IU corresponding to iu_uid from the OutputBuffer, retracting it from the system.''' + '''Retracts an IU and removes it from the OutputBuffer.''' if iu is None: if iu_uid is None: return None else: - if iu_uid not in self. _iu_store: + if iu_uid not in self._iu_store: raise ipaaca.exception.IUNotFoundError(iu_uid) iu = self._iu_store[iu_uid] # unpublish the IU @@ -505,12 +507,13 @@ class OutputBuffer(Buffer): informer.publishData(iu) def _retract_iu(self, iu): - '''Retract (unpublish) an IU.''' + '''Retract an IU.''' iu_retraction = ipaaca_pb2.IURetraction() iu_retraction.uid = iu.uid iu_retraction.revision = iu.revision informer = self._get_informer(iu._category) informer.publishData(iu_retraction) + iu._retracted = True def _send_iu_commission(self, iu, writer_name): '''Send IU commission. diff --git a/ipaacalib/python/src/ipaaca/iu.py b/ipaacalib/python/src/ipaaca/iu.py index fd55bd7..66f139f 100644 --- a/ipaacalib/python/src/ipaaca/iu.py +++ b/ipaacalib/python/src/ipaaca/iu.py @@ -4,7 +4,7 @@ # "Incremental Processing Architecture # for Artificial Conversational Agents". # -# Copyright (c) 2009-2014 Social Cognitive Systems Group +# Copyright (c) 2009-2015 Social Cognitive Systems Group # CITEC, Bielefeld University # # http://opensource.cit-ec.de/projects/ipaaca/ @@ -114,7 +114,7 @@ class IUInterface(object): s += k+":'"+unicode(v)+"', " s += "} " s += "links={ " - for t,ids in self.get_all_links().items(): + for t, ids in self.get_all_links().items(): s += t+":'"+unicode(ids)+"', " s += "} " s += "}" @@ -173,9 +173,9 @@ class IUInterface(object): if self._buffer is None: self._payload_type = type else: - raise IpaacaException('The IU is already in a buffer, cannot change payload type anymore.') + raise ipaaca.exception.IpaacaError('The IU is already in a buffer, cannot change payload type anymore.') payload_type = property( - fget=_get_payload_type, + fget=_get_payload_type, fset=_set_payload_type, doc='Type of the IU payload') @@ -209,7 +209,7 @@ class IUInterface(object): return self._buffer def _set_buffer(self, buffer): if self._buffer is not None: - raise IpaacaException('The IU is already in a buffer, cannot move it.') + raise ipaaca.exception.IpaacaError('The IU is already in a buffer, cannot move it.') self._buffer = buffer buffer = property( fget=_get_buffer, @@ -220,7 +220,7 @@ class IUInterface(object): return self._owner_name def _set_owner_name(self, owner_name): if self._owner_name is not None: - raise Exception('The IU already has an owner name, cannot change it.') + raise ipaaca.exception.IpaacaError('The IU already has an owner name, cannot change it.') self._owner_name = owner_name owner_name = property( fget=_get_owner_name, @@ -241,7 +241,9 @@ class IU(IUInterface): self._payload = ipaaca.payload.Payload(iu=self) def _modify_links(self, is_delta=False, new_links={}, links_to_remove={}, writer_name=None): - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) with self.revision_lock: # modify links locally @@ -258,7 +260,9 @@ class IU(IUInterface): def _modify_payload(self, is_delta=True, new_items={}, keys_to_remove=[], writer_name=None): """Modify the payload: add or remove items from this payload locally and send update.""" - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) with self.revision_lock: # set item locally @@ -279,23 +283,33 @@ class IU(IUInterface): self._revision += 1 def _internal_commit(self, writer_name=None): - if self.committed: - raise ipaaca.exception.IUCommittedError(self) + if self._committed: + return + if self._retracted: + raise ipaaca.exception.IURetractedError(self) with self.revision_lock: - if not self._committed: - self._increase_revision_number() - self._committed = True - if self.buffer is not None: - self.buffer._send_iu_commission(self, writer_name=writer_name) + self._increase_revision_number() + self._committed = True + if self.buffer is not None: + self.buffer._send_iu_commission(self, writer_name=writer_name) def commit(self): """Commit to this IU.""" return self._internal_commit() + def retract(self): + if self._buffer: + self._buffer.remove(self) + self._buffer = None + else: + self._retracted = True + def _get_payload(self): return self._payload def _set_payload(self, new_pl, writer_name=None): - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) with self.revision_lock: self._increase_revision_number() @@ -316,7 +330,7 @@ class IU(IUInterface): def _set_buffer(self, buffer): if self._buffer is not None: - raise Exception('The IU is already in a buffer, cannot move it.') + raise ipaaca.exception.IpaacaError('The IU is already in a buffer, cannot move it.') self._buffer = buffer self.owner_name = buffer.unique_name self._payload.owner_name = buffer.unique_name @@ -364,7 +378,9 @@ class Message(IU): if self.is_published: LOGGER.info('Info: modifying a Message after sending has no global effects') else: - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) with self.revision_lock: self._increase_revision_number() @@ -385,7 +401,7 @@ class Message(IU): def _set_buffer(self, buffer): if self._buffer is not None: - raise Exception('The IU is already in a buffer, cannot move it.') + raise ipaaca.exception.IpaacaError('The IU is already in a buffer, cannot move it.') self._buffer = buffer self.owner_name = buffer.unique_name self._payload.owner_name = buffer.unique_name @@ -414,7 +430,6 @@ class RemoteMessage(IUInterface): self._category = category self.owner_name = owner_name self._committed = committed - self._retracted = False # NOTE Since the payload is an already-existant Payload which we didn't modify ourselves, # don't try to invoke any modification checks or network updates ourselves either. # We are just receiving it here and applying the new data. @@ -481,7 +496,6 @@ class RemotePushIU(IUInterface): self._category = category self.owner_name = owner_name self._committed = committed - self._retracted = False # NOTE Since the payload is an already-existant Payload which we didn't modify ourselves, # don't try to invoke any modification checks or network updates ourselves either. # We are just receiving it here and applying the new data. @@ -490,9 +504,11 @@ class RemotePushIU(IUInterface): def _modify_links(self, is_delta=False, new_links={}, links_to_remove={}, writer_name=None): """Modify the links: add or remove item from this payload remotely and send update.""" - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) - if self.read_only: + if self._read_only: raise ipaaca.exception.IUReadOnlyError(self) requested_update = ipaaca.converter.IULinkUpdate( uid=self.uid, @@ -510,9 +526,11 @@ class RemotePushIU(IUInterface): def _modify_payload(self, is_delta=True, new_items={}, keys_to_remove=[], writer_name=None): """Modify the payload: add or remove item from this payload remotely and send update.""" - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) - if self.read_only: + if self._read_only: raise ipaaca.exception.IUReadOnlyError(self) requested_update = ipaaca.converter.IUPayloadUpdate( uid=self.uid, @@ -531,30 +549,32 @@ class RemotePushIU(IUInterface): def commit(self): """Commit to this IU.""" - if self.read_only: - raise ipaaca.exception.IUReadOnlyError(self) if self._committed: - # ignore commit requests when already committed return + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._read_only: + raise ipaaca.exception.IUReadOnlyError(self) + commission_request = ipaaca_pb2.IUCommission() + commission_request.uid = self.uid + commission_request.revision = self.revision + commission_request.writer_name = self.buffer.unique_name + remote_server = self.buffer._get_remote_server(self) + new_revision = remote_server.commit(commission_request) + if new_revision == 0: + raise ipaaca.exception.IUUpdateFailedError(self) else: - commission_request = ipaaca_pb2.IUCommission() - commission_request.uid = self.uid - commission_request.revision = self.revision - commission_request.writer_name = self.buffer.unique_name - remote_server = self.buffer._get_remote_server(self) - new_revision = remote_server.commit(commission_request) - if new_revision == 0: - raise ipaaca.exception.IUUpdateFailedError(self) - else: - self._revision = new_revision - self._committed = True + self._revision = new_revision + self._committed = True def _get_payload(self): return self._payload def _set_payload(self, new_pl): - if self.committed: + if self._retracted: + raise ipaaca.exception.IURetractedError(self) + if self._committed: raise ipaaca.exception.IUCommittedError(self) - if self.read_only: + if self._read_only: raise ipaaca.exception.IUReadOnlyError(self) requested_update = ipaaca.converter.IUPayloadUpdate( uid=self.uid, -- GitLab