Skip to content
Snippets Groups Projects
Commit 4d35af63 authored by Ramin Yaghoubzadeh's avatar Ramin Yaghoubzadeh
Browse files

refactoring python to match the Java "one-Payload-class" version

parent 1661f4de
No related branches found
No related tags found
No related merge requests found
**/.*.swp
...@@ -21,7 +21,7 @@ message IU { ...@@ -21,7 +21,7 @@ message IU {
required string uid = 1; required string uid = 1;
required uint32 revision = 2; required uint32 revision = 2;
required string category = 3 [default = "undef"]; required string category = 3 [default = "undef"];
optional string type = 4; required string payload_type = 4 [default = "MAP"];
required string owner_name = 5; required string owner_name = 5;
required bool committed = 6 [default = false]; required bool committed = 6 [default = false];
required AccessMode access_mode = 7 [default = PUSH]; required AccessMode access_mode = 7 [default = PUSH];
......
...@@ -41,7 +41,7 @@ def enum(*sequential, **named): ...@@ -41,7 +41,7 @@ def enum(*sequential, **named):
def pack_typed_payload_item(protobuf_object, key, value): def pack_typed_payload_item(protobuf_object, key, value):
protobuf_object.key = str(key) protobuf_object.key = str(key)
protobuf_object.value = str(value) protobuf_object.value = str(value)
protobuf_object.type = 'str' # TODO: more types protobuf_object.payload_type = 'str' # TODO: more types
def unpack_typed_payload_item(protobuf_object): def unpack_typed_payload_item(protobuf_object):
...@@ -109,159 +109,21 @@ class IUReadOnlyError(Exception): ...@@ -109,159 +109,21 @@ class IUReadOnlyError(Exception):
## --- Generation Architecture ----------------------------------------------- ## --- Generation Architecture -----------------------------------------------
class LocalPayload(dict):#{{{ class Payload(dict):
"""Payload of IUs held locally, i.e., in an OutputBuffer."""
def __init__(self, iu, writer_name=None, new_payload=None): def __init__(self, iu, writer_name=None, new_payload=None):
"""Create local payload object. pl = {} if new_payload is None else new_payload
self.iu = iu
Keyword arguments: self.iu._set_payload(payload=self, is_delta=False, new_items=pl, keys_to_remove=[], writer_name=writer_name)
iu -- IU holding this payload for k, v in pl.items():
writer_name -- @RAMIN: What is the reason to specify it here? dict.__setitem__(self, k, v)
new_payload -- a payload dictionary to initialise this object
with, or None for an empty payload
"""
super(LocalPayload, self).__init__()
self._iu = iu
if new_payload is not None:
for k, v in new_payload.items():
dict.__setitem__(self, k, v)
if self._iu.is_published:
self._iu.buffer._send_iu_payload_update(
self._iu,
revision=iu.revision,
is_delta=False,
new_items=new_payload,
keys_to_remove=[],
writer_name = self._iu.owner_name if writer_name is None else writer_name)
# @RAMIN: Not needed, right?
#def __contains__(self, k):
# return dict.__contains__(self, k)
#def __getitem__(self, k):
# return dict.__getitem__(self, k)
def __setitem__(self, k, v, writer_name=None): def __setitem__(self, k, v, writer_name=None):
"""Set an item from this payload locally and send update.""" self.iu._set_payload(payload=self, is_delta=True, new_items={k:v}, keys_to_remove=[], writer_name=writer_name)
if self._iu.committed: result = dict.__setitem__(self, k, v)
raise IUCommittedError(self._iu)
with self._iu.revision_lock:
# set item locally
result = dict.__setitem__(self, k, v)
self._iu._increase_revision_number()
if self._iu.is_published:
# send update to remote holders
self._iu.buffer._send_iu_payload_update(
self._iu,
revision=self._iu.revision,
is_delta=True,
new_items={k:v},
keys_to_remove=[],
writer_name=self._iu.owner_name if writer_name is None else writer_name)
return result
def __delitem__(self, k, writer_name=None): def __delitem__(self, k, writer_name=None):
"""Delete an item from this payload locally and send update.""" self.iu._set_payload(payload=self, is_delta=True, new_items={}, keys_to_remove=[k], writer_name=writer_name)
if self._iu.committed: result = dict.__delitem__(self, k)
raise IUCommittedError(self._iu)
with self._iu.revision_lock:
# delete item locally
result = dict.__delitem__(self, k)
self._iu._increase_revision_number()
if self._iu.is_published:
# send update to remote holders
self._iu.buffer._send_iu_payload_update(
self._iu,
revision=self._iu.revision,
is_delta=True,
new_items={},
keys_to_remove=[k],
writer_name=self._iu.owner_name if writer_name is None else writer_name)
return result
#}}}
class RemotePushPayload(dict):#{{{
"""Payload of an IU of type 'PUSH' hold remotely, i.e., in an InputBuffer."""
def __init__(self, remote_push_iu, new_payload):
"""Create remote payload object.
Keyword arguments:
remote_push_iu -- remote IU holding this payload
new_payload -- payload dict to initialise this remote payload with
"""
super(RemotePushPayload, self).__init__()
self._remote_push_iu = remote_push_iu
if new_payload is not None:
for k,v in new_payload.items():
dict.__setitem__(self, k, v)
def __setitem__(self, k, v):
"""Set item in this payload.
Requests item setting from the OutputBuffer holding the local version
of this IU. Returns when permission is granted and item is set;
otherwise raises an IUUpdateFailedError.
"""
if self._remote_push_iu.committed:
raise IUCommittedError(self._remote_push_iu)
if self._remote_push_iu.read_only:
raise IUReadOnlyError(self._remote_push_iu)
requested_update = IUPayloadUpdate(
uid=self._remote_push_iu.uid,
revision=self._remote_push_iu.revision,
is_delta=True,
writer_name=self._remote_push_iu.buffer.unique_name,
new_items={k:v},
keys_to_remove=[])
remote_server = self._remote_push_iu.buffer._get_remote_server(self._remote_push_iu)
new_revision = remote_server.updatePayload(requested_update)
if new_revision == 0:
raise IUUpdateFailedError(self._remote_push_iu)
else:
self._remote_push_iu._revision = new_revision
dict.__setitem__(self, k, v)
def __delitem__(self, k):
"""Delete item in this payload.
Requests item deletion from the OutputBuffer holding the local version
of this IU. Returns when permission is granted and item is deleted;
otherwise raises an IUUpdateFailedError.
"""
if self._remote_push_iu.committed:
raise IUCommittedError(self._remote_push_iu)
if self._remote_push_iu.read_only:
raise IUReadOnlyError(self._remote_push_iu)
requested_update = IUPayloadUpdate(
uid=self._remote_push_iu.uid,
revision=self._remote_push_iu.revision,
is_delta=True,
writer_name=self._remote_push_iu.buffer.unique_name,
new_items={},
keys_to_remove=[k])
remote_server = self._remote_push_iu.buffer._get_remote_server(self._remote_push_iu)
new_revision = remote_server.updatePayload(requested_update)
if new_revision == 0:
raise IUUpdateFailedError(self._remote_push_iu)
else:
self._remote_push_iu._revision = new_revision
dict.__delitem__(self, k)
def _remotely_enforced_setitem(self, k, v):
"""Sets an item when requested remotely."""
return dict.__setitem__(self, k, v)
def _remotely_enforced_delitem(self, k):
"""Deletes an item when requested remotely."""
return dict.__delitem__(self, k)
#}}}
class IUInterface(object): class IUInterface(object):
"""Base class of all specialised IU classes.""" """Base class of all specialised IU classes."""
...@@ -277,7 +139,7 @@ class IUInterface(object): ...@@ -277,7 +139,7 @@ class IUInterface(object):
self._uid = uid self._uid = uid
self._revision = None self._revision = None
self._category = None self._category = None
self._type = None self._payload_type = None
self._owner_name = None self._owner_name = None
self._committed = False self._committed = False
self._access_mode = access_mode self._access_mode = access_mode
...@@ -293,9 +155,9 @@ class IUInterface(object): ...@@ -293,9 +155,9 @@ class IUInterface(object):
return self._category return self._category
category = property(fget=_get_category, doc='Category of the IU.') category = property(fget=_get_category, doc='Category of the IU.')
def _get_type(self): def _get_payload_type(self):
return self._type return self._payload_type
type = property(fget=_get_type, doc='Type of the IU') payload_type = property(fget=_get_payload_type, doc='Type of the IU payload')
def _get_committed(self): def _get_committed(self):
return self._committed return self._committed
...@@ -344,14 +206,32 @@ class IU(IUInterface):#{{{ ...@@ -344,14 +206,32 @@ class IU(IUInterface):#{{{
"""A local IU.""" """A local IU."""
def __init__(self, access_mode=IUAccessMode.PUSH, read_only=False, category='undef', _type='undef'): def __init__(self, access_mode=IUAccessMode.PUSH, read_only=False, category='undef', _payload_type='MAP'):
super(IU, self).__init__(uid=None, access_mode=access_mode, read_only=read_only) super(IU, self).__init__(uid=None, access_mode=access_mode, read_only=read_only)
self._revision = 1 self._revision = 1
self._category = category self._category = category
self._type = _type self._payload_type = _payload_type
self._payload = LocalPayload(iu=self) self._payload = Payload(iu=self)
self.revision_lock = threading.Lock() self.revision_lock = threading.Lock()
def _set_payload(payload, is_delta=True, new_items={}, keys_to_remove=[], writer_name=None):
"""Set an item from this payload locally and send update."""
if self.committed:
raise IUCommittedError(self)
with self.revision_lock:
# set item locally
self._increase_revision_number()
if self.is_published:
# send update to remote holders
self.buffer._send_iu_payload_update(
self,
revision=self.revision,
is_delta=True,
new_items={k:v},
keys_to_remove=[],
writer_name=self.owner_name if writer_name is None else writer_name)
return result
def _increase_revision_number(self): def _increase_revision_number(self):
self._revision += 1 self._revision += 1
...@@ -387,7 +267,7 @@ class IU(IUInterface):#{{{ ...@@ -387,7 +267,7 @@ class IU(IUInterface):#{{{
raise IUCommittedError(self) raise IUCommittedError(self)
with self.revision_lock: with self.revision_lock:
self._increase_revision_number() self._increase_revision_number()
self._payload = LocalPayload( self._payload = Payload(
iu=self, iu=self,
writer_name=None if self.buffer is None else (self.buffer.unique_name if writer_name is None else writer_name), writer_name=None if self.buffer is None else (self.buffer.unique_name if writer_name is None else writer_name),
new_payload=new_pl) new_payload=new_pl)
...@@ -428,15 +308,34 @@ class RemotePushIU(IUInterface):#{{{ ...@@ -428,15 +308,34 @@ class RemotePushIU(IUInterface):#{{{
"""A remote IU with access mode 'PUSH'.""" """A remote IU with access mode 'PUSH'."""
def __init__(self, uid, revision, read_only, owner_name, category, type, committed, payload): def __init__(self, uid, revision, read_only, owner_name, category, payload_type, committed, payload):
super(RemotePushIU, self).__init__(uid=uid, access_mode=IUAccessMode.PUSH, read_only=read_only) super(RemotePushIU, self).__init__(uid=uid, access_mode=IUAccessMode.PUSH, read_only=read_only)
self._revision = revision self._revision = revision
self._category = category self._category = category
self.owner_name = owner_name self.owner_name = owner_name
self._type = type self._payload_type = payload_type
self._committed = committed self._committed = committed
self._payload = RemotePushPayload(remote_push_iu=self, new_payload=payload) self._payload = Payload(iu=self, new_payload=payload)
def _set_payload(payload, is_delta=True, new_items={}, keys_to_remove=[], writer_name=None):
if self.committed:
raise IUCommittedError(self)
if self.read_only:
raise IUReadOnlyError(self)
requested_update = IUPayloadUpdate(
uid=self.uid,
revision=self.revision,
is_delta=is_delta,
writer_name=self.buffer.unique_name,
new_items=new_items,
keys_to_remove=keys_to_remove)
remote_server = self.buffer._get_remote_server(self)
new_revision = remote_server.updatePayload(requested_update)
if new_revision == 0:
raise IUUpdateFailedError(self)
else:
self._revision = new_revision
def __str__(self): def __str__(self):
s = "RemotePushIU{ " s = "RemotePushIU{ "
s += "uid="+self._uid+" " s += "uid="+self._uid+" "
...@@ -489,7 +388,7 @@ class RemotePushIU(IUInterface):#{{{ ...@@ -489,7 +388,7 @@ class RemotePushIU(IUInterface):#{{{
raise IUUpdateFailedError(self) raise IUUpdateFailedError(self)
else: else:
self._revision = new_revision self._revision = new_revision
self._payload = RemotePushPayload(remote_push_iu=self, new_payload=new_pl) self._payload = Payload(iu=self, new_payload=new_pl)
payload = property( payload = property(
fget=_get_payload, fget=_get_payload,
fset=_set_payload, fset=_set_payload,
...@@ -503,7 +402,7 @@ class RemotePushIU(IUInterface):#{{{ ...@@ -503,7 +402,7 @@ class RemotePushIU(IUInterface):#{{{
for k, v in update.new_items.items(): self.payload._remotely_enforced_setitem(k, v) for k, v in update.new_items.items(): self.payload._remotely_enforced_setitem(k, v)
else: else:
# using '_payload' to circumvent the local writing methods # using '_payload' to circumvent the local writing methods
self._payload = RemotePushPayload(remote_push_iu=self, new_payload=update.new_items) self._payload = Payload(iu=self, new_payload=update.new_items)
def _apply_commission(self): def _apply_commission(self):
"""Apply commission to the IU""" """Apply commission to the IU"""
...@@ -541,7 +440,7 @@ class IUConverter(rsb.transport.converter.Converter):#{{{ ...@@ -541,7 +440,7 @@ class IUConverter(rsb.transport.converter.Converter):#{{{
pbo.uid = iu._uid pbo.uid = iu._uid
pbo.revision = iu._revision pbo.revision = iu._revision
pbo.category = iu._category pbo.category = iu._category
pbo.type = iu._type pbo.payload_type = iu._payload_type
pbo.owner_name = iu._owner_name pbo.owner_name = iu._owner_name
pbo.committed = iu._committed pbo.committed = iu._committed
pbo.access_mode = ipaaca_pb2.IU.PUSH # TODO pbo.access_mode = ipaaca_pb2.IU.PUSH # TODO
...@@ -567,7 +466,7 @@ class IUConverter(rsb.transport.converter.Converter):#{{{ ...@@ -567,7 +466,7 @@ class IUConverter(rsb.transport.converter.Converter):#{{{
read_only = pbo.read_only, read_only = pbo.read_only,
owner_name = pbo.owner_name, owner_name = pbo.owner_name,
category = pbo.category, category = pbo.category,
type = pbo.type, payload_type = pbo.payload_type,
committed = pbo.committed, committed = pbo.committed,
payload=_payload payload=_payload
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment