"""
Module **sesf.msgtransfer2.serviceparts** has class ``ServiceParts``,
which has the component functions of sesf.msgtransfer2.service.ppy.
Each function ``f`` in the pseudo-Python class gives rise to six functions:
``f_CIC``, ``f_COC``, ``f_CU``, ``f_RIC``, ``f_ROC``, ``f_RU``.
"""
from random import randint
[docs]class ServiceParts():
def __init__(self):
"""
Throughout j ranges over 0..1:
- ending is true iff end(0) or end(1) has been called.
- ongoing_send[j] is true iff a send(j,.) call is ongoing.
- closed_send[j] is true iff a send(j,.) call has returned False.
- ongoing_recv[j] is true iff a send(j,.) call is ongoing.
- closed_recv[j] is true iff a send(j,.) call has returned (False,).
- sent[j] is the sequence of messages sent in send(j,.) calls.
- nrcvd[j] is the number of messages returned in recv(j) calls.
"""
self.ending = False
self.ongoing_send = [False, False]
self.closed_send = [False, False]
self.ongoing_recv = [False, False]
self.closed_recv = [False, False]
self.sent = [[], []]
self.nrcvd = [0, 0]
### send(self, j, msg) components #########################################
# send.CIC input_version: return True | False
def send_CIC(self, j, msg):
return (j in (0, 1) and
not self.ongoing_send[j] and not self.closed_send[j])
# send.COC output_version: return (0,) | (1, msg)
def send_COC(self, j):
if self.ongoing_send[j] or self.closed_send[j]:
return (0,)
else:
msg = randint(1, 10000)
return (1, msg)
# send.CU
def send_CU(self, j, msg):
self.sent[j].append(msg)
self.ongoing_send[j] = True
# send.RIC input_version: return True | False
def send_RIC(self, j, rval):
return (rval == True or (rval == False and self.ending))
# send.ROC output_version: return (1, True) | (1, False)
def send_ROC(self, j):
if not self.ending:
return (1, True)
else:
# return (1, True | False)
return (1, (1 == randint(0,1)))
# send.RU: rval is True | False
def send_RU(self, j, rval):
self.ongoing_send[j] = False
if not rval:
self.closed_send[j] = True
### recv(self, j) components ###########################################
# recv.CIC input_version: return True | False
def recv_CIC(self, j):
return (j in (0, 1) and
not self.ongoing_recv[j] and not self.closed_recv[j])
# recv.COC output_version: return (0,) | (1,)
def recv_COC(self, j):
if self.ongoing_recv[j] or self.closed_recv[j]:
return (0,)
else:
return (1,)
# recv.CU
def recv_CU(self, j):
self.ongoing_recv[j] = True
# recv.RIC input_version: return True | False
# rval is (False,) | (True, msg)
# TODO?: randomize if ending is rval
def recv_RIC(self, j, rval):
if rval == (False,):
return self.ending
else:
flag, msg = rval
return (flag == True and self.nrcvd[j] < len(self.sent[1-j])
and msg == self.sent[1-j][self.nrcvd[j]])
# recv.ROC output_version: return (0,) | (1,(False,)) | (1,(True,msg))
def recv_ROC(self, j):
if self.nrcvd[j] >= len(self.sent[1-j]):
# nothing to receive
if self.ending:
return (1, (False,))
else:
return (0,)
else:
# incoming msg
if self.ending and randint(0,1) == 0:
return (1, (False,))
else:
msg = self.sent[1-j][self.nrcvd[j]]
return (1, (True, msg))
# recv.RU: rval is (False,) | (True,msg)
def recv_RU(self, j, rval):
self.ongoing_recv[j] = False
if rval == (False,):
self.closed_recv[j] = True
else:
flag, msg = rval
self.nrcvd[j] += 1
return rval
### end(self, j) components ###########################################
# end.CIC input_version: return True | False
def end_CIC(self, j):
return (j in (0,1) and not self.ending)
# end.COC output_version: return (0,) | (1,)
def end_COC(self, j):
if self.ending:
return (0,)
else:
return (1,)
# end.CU
def end_CU(self, j):
self.ending = True
# end.RIC input_version: return True
def end_RIC(self, j):
return True
# end.ROC output_version: return (1,)
def end_ROC(self, j):
return (1,)
# end.RU
def end_RU(self, j):
pass