"""
Module **sesf.msgtransfer.serviceparts** has class ``ServiceParts``,
which has the component functions of sesf.msgtransfer.service.
"""
from random import randint
[docs]class ServiceParts():
def __init__(self, num_nodes):
"""
Throughout, j ranges over 0, ..., num_nodes-1:
- ending is true iff end(j) has been called for some j.
- 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 recv(j) call is ongoing.
- closed_recv[j] is true iff a recv(j,) call has returned (False,).
- sent[(j,k)] is the sequence of messages sent in send(j,k,.) calls.
- nrcvd[(j,k)] is the number of messages from j received in recv(k) calls.
"""
self.num_nodes = num_nodes
self.ending = False
self.ongoing_send = [False for k in range(num_nodes)]
self.closed_send = [False for k in range(num_nodes)]
self.ongoing_recv = [False for k in range(num_nodes)]
self.closed_recv = [False for k in range(num_nodes)]
self.sent = {(j,k) : []
for k in range(num_nodes)
for j in range(num_nodes) if k != j}
self.nrcvd = {(j,k) : 0
for k in range(num_nodes)
for j in range(num_nodes) if k != j}
### input send(self, j, k, msg) components #############################
# send.CIC input_version: return True | False
def send_CIC(self, j, k, msg):
return (0 <= j < self.num_nodes
and not self.ongoing_send[j] and not self.closed_send[j]
and 0 <= k < self.num_nodes and j != k)
# send.COC output_version: return (0,) | (1, k, msg)
def send_COC(self, j):
if self.ongoing_send[j] or self.closed_send[j]:
return (0,)
else:
# genrate random destination and random msg (in 1..10000)
k = (j + randint(1, self.num_nodes-1)) % self.num_nodes
msg = (j, randint(1, 10000))
return (1, k, msg)
# send.CU
def send_CU(self, j, k, msg):
self.sent[(j,k)].append(msg)
self.ongoing_send[j] = True
# send.RIC input_version: return True | False
def send_RIC(self, j, rval):
return (rval or 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
def send_RU(self, j, rval):
self.ongoing_send[j] = False
if not rval:
self.closed_send[j] = True
### input recv(self, j) components #####################################
# recv.CIC input version
def recv_CIC(self, j):
return (0 <= j < self.num_nodes
and not (self.ongoing_recv[j] or 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 input version
def recv_CU(self, j):
self.ongoing_recv[j] = True
# recv.RIC input version
def recv_RIC(self, j, rval):
# rval is (False,) or (True, msg, k)
if rval == (False,):
return self.ending
else:
flag, msg, k = rval
return (flag == True and 0 <= k < self.num_nodes
and self.nrcvd[(k,j)] < len(self.sent[(k,j)])
and msg == self.sent[(k,j)][self.nrcvd[(k,j)]])
# recv.ROC output version: return (0,) | (1,(False,)) | (1,(True,msg,k))
def recv_ROC(self, j):
rcvable = [k for k in range(self.num_nodes)
if k != j and self.nrcvd[(k,j)] < len(self.sent[(k,j)])]
if rcvable == []:
if self.ending:
return (1, (False,))
else:
return (0,)
else:
if self.ending and randint(0,1) == 0:
return (1, (False,))
else:
k = rcvable[randint(0, len(rcvable)-1)]
msg = self.sent[(k,j)][self.nrcvd[(k,j)]]
return (1, (True, msg, k))
# recv.RU
def recv_RU(self, j, rval):
self.ongoing_recv[j] = False
if rval == (False,):
self.closed_recv[j] = True
else:
flag, msg, k = rval
self.nrcvd[(k,j)] += 1
### input j.end(self, j) components ##################################
# end.CIC input_version: return True | False
def end_CIC(self, j):
return (0 <= j < self.num_nodes 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
###### END class Service of module msgtransfer.service ############
if __name__ == '__main__':
serviceparts = ServiceParts(8)
print('msgtransfer.serviceparts.ServiceParts instantiated successfully')