From d59283465e8c11ba940572e2d309847624016f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Berker=20Ac=C4=B1r?= <30311105+berkeracir@users.noreply.github.com> Date: Sun, 25 Apr 2021 20:25:04 +0300 Subject: [PATCH 1/4] Fix contributors list item --- CONTRIBUTORS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9a8ee5a..6b324da 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,3 +1,3 @@ # Contributors --[Berker Acır](https://github.com/berkeracir) +- [Berker Acır](https://github.com/berkeracir) -- GitLab From 383015b01462e0d35066871a85705d5a1515fb83 Mon Sep 17 00:00:00 2001 From: berkeracir Date: Tue, 18 May 2021 00:27:05 +0300 Subject: [PATCH 2/4] add implementation and test of RicartAgrawala algorithm for Mutual Exclusion --- MutualExclusion/RicartAgrawala.py | 181 +++++++++++ tests/MutualExclusion/testRicartAgrawala.py | 325 ++++++++++++++++++++ 2 files changed, 506 insertions(+) create mode 100644 MutualExclusion/RicartAgrawala.py create mode 100644 tests/MutualExclusion/testRicartAgrawala.py diff --git a/MutualExclusion/RicartAgrawala.py b/MutualExclusion/RicartAgrawala.py new file mode 100644 index 0000000..1ddc2ab --- /dev/null +++ b/MutualExclusion/RicartAgrawala.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python +""" + Implementation of the Ricart-Agrawala Algorithm for mutual exclusion. +""" + +__author__ = "Berker Acır" +__contact__ = "berkeracir159@gmail.com" +__copyright__ = "Copyright 2021, WINSLAB" +__credits__ = ["Berker Acır"] +__date__ = "2021/04/24" +__deprecated__ = False +__email__ = "berkeracir159@gmail.com" +__license__ = "GPLv3" +__maintainer__ = "developer" +__status__ = "Production" +__version__ = "0.0.1" + +from enum import Enum +from time import sleep + +from Ahc import ComponentModel, Event, EventTypes, GenericMessage, GenericMessagePayload, GenericMessageHeader, inf, \ + Topology + + +class RicartAgrawalaEventTypes(Enum): + REQUEST = "REQUEST" + REPLY = "REPLY" + PRIVILEGE = "PRIVILEGE" + + +class RicartAgrawalaMessageTypes(Enum): + REQUEST = "REQUEST" + REPLY = "REPLY" + + +class RicartAgrawalaMessageHeader(GenericMessageHeader): + + def __init__(self, messageType, messageFrom, messageTo, nextHop=float('inf'), interfaceID=float('inf'), + sequenceID=-1): + super().__init__(messageType, messageFrom, messageTo, nextHop, interfaceID, sequenceID) + + +class RicartAgrawalaMessagePayload(GenericMessagePayload): + + def __init__(self, clock, nodeID): + self.clock = clock + self.nodeID = nodeID + + +class RicartAgrawalaNode(ComponentModel): + privilegeSleepAmount = 0.1 + + def __init__(self, componentName, componentID): + super().__init__(componentName, componentID) + + self.eventhandlers[RicartAgrawalaEventTypes.REQUEST] = self.request_received + self.eventhandlers[RicartAgrawalaEventTypes.REPLY] = self.reply_received + self.eventhandlers[RicartAgrawalaEventTypes.PRIVILEGE] = self.on_privilege + + self.clock = 0 + self.havePendingRequest = False + self.pendingRequestClock = None + self.isPrivileged = False + + self.deferredRequests = list() + self.receivedReplies = set() + self.otherNodeIDs = set() + + self.privilegeCount = 0 + self.sentRequestCount = 0 + self.sentReplyCount = 0 + self.receivedRequestCount = 0 + self.receivedReplyCount = 0 + self.forwardedMessageCount = 0 + + def on_init(self, eventobj: Event): + self.otherNodeIDs = set(Topology().nodes.keys()) + self.otherNodeIDs.remove(self.componentinstancenumber) + + def on_message_from_bottom(self, eventobj: Event): + message = eventobj.eventcontent + header = message.header + messageType = header.messagetype + messageTo = header.messageto + + if messageTo == self.componentinstancenumber: + if messageType == RicartAgrawalaMessageTypes.REQUEST: + eventobj.event = RicartAgrawalaEventTypes.REQUEST + self.send_self(eventobj) + elif messageType == RicartAgrawalaMessageTypes.REPLY: + eventobj.event = RicartAgrawalaEventTypes.REPLY + self.send_self(eventobj) + else: + nextHop = Topology().get_next_hop(self.componentinstancenumber, messageTo) + interfaceID = f"{self.componentinstancenumber}-{nextHop}" + + if nextHop != inf and nextHop != self.componentinstancenumber: + self.forwardedMessageCount += 1 + header.nexthop = nextHop + header.interfaceid = interfaceID + self.send_down(Event(self, EventTypes.MFRT, message)) + + def request_received(self, eventobj: Event): + self.receivedRequestCount += 1 + receivedRequestClock = eventobj.eventcontent.payload.clock + receivedRequestNodeID = eventobj.eventcontent.payload.nodeID + + if not self.isPrivileged: # Not privileged + if self.havePendingRequest: # Have pending request + if receivedRequestClock < self.pendingRequestClock: + isMessageDeferred = False + elif receivedRequestClock == self.pendingRequestClock and receivedRequestNodeID < self.componentinstancenumber: + isMessageDeferred = False + else: + isMessageDeferred = True + else: # Does not have pending request + isMessageDeferred = False + else: # Privileged + isMessageDeferred = True + + if isMessageDeferred: + self.deferredRequests.append(eventobj) + else: + if self.clock <= receivedRequestClock: + self.clock = receivedRequestClock + 1 + self.send_reply(receivedRequestNodeID) + + def reply_received(self, eventobj: Event): + self.receivedReplyCount += 1 + replyFrom = eventobj.eventcontent.payload.messagepayload + self.receivedReplies.add(replyFrom) + + if len(self.receivedReplies) == len(self.otherNodeIDs): + self.send_self(Event(self, RicartAgrawalaEventTypes.PRIVILEGE, None)) + elif len(self.receivedReplies) > len(self.otherNodeIDs): + raise RuntimeError("Received reply message count exceeded expected limit!") + + def on_privilege(self, eventobj: Event): + self.isPrivileged = True + self.havePendingRequest = False + self.receivedReplies.clear() + + self.privilegeCount += 1 + sleep(self.privilegeSleepAmount) + + self.isPrivileged = False + self.send_replies_to_deferred_requests() + + def send_request(self): + self.sentRequestCount += 1 + self.havePendingRequest = True + self.pendingRequestClock = self.clock + + for nodeID in self.otherNodeIDs: + nextHop = Topology().get_next_hop(self.componentinstancenumber, nodeID) + interfaceID = f"{self.componentinstancenumber}-{nextHop}" + header = RicartAgrawalaMessageHeader(RicartAgrawalaMessageTypes.REQUEST, self.componentinstancenumber, + nodeID, nextHop, interfaceID) + payload = RicartAgrawalaMessagePayload(self.pendingRequestClock, self.componentinstancenumber) + message = GenericMessage(header, payload) + self.send_down(Event(self, EventTypes.MFRT, message)) + + def send_reply(self, nodeID): + self.sentReplyCount += 1 + nextHop = Topology().get_next_hop(self.componentinstancenumber, nodeID) + interfaceID = f"{self.componentinstancenumber}-{nextHop}" + header = RicartAgrawalaMessageHeader(RicartAgrawalaMessageTypes.REPLY, self.componentinstancenumber, nodeID, + nextHop, interfaceID) + payload = GenericMessagePayload(self.componentinstancenumber) + message = GenericMessage(header, payload) + self.send_down(Event(self, EventTypes.MFRT, message)) + + def send_replies_to_deferred_requests(self): + while self.deferredRequests: + event = self.deferredRequests.pop(0) + deferredRequestNodeID = event.eventcontent.payload.nodeID + deferredRequestClock = event.eventcontent.payload.clock + + if self.clock <= deferredRequestClock: + self.clock = deferredRequestClock + 1 + self.send_reply(deferredRequestNodeID) diff --git a/tests/MutualExclusion/testRicartAgrawala.py b/tests/MutualExclusion/testRicartAgrawala.py new file mode 100644 index 0000000..fc1a7e5 --- /dev/null +++ b/tests/MutualExclusion/testRicartAgrawala.py @@ -0,0 +1,325 @@ +import math +import random +from enum import Enum + +import matplotlib.pyplot as plt +import networkx as nx +import threading +from time import sleep +from itertools import combinations, groupby +from math import cos, sin, atan2, radians + +from MutualExclusion.RicartAgrawala import RicartAgrawalaNode +from Ahc import Topology +from Channels import P2PFIFOPerfectChannel + +FPS = 24.0 + +EDGE_COLOR = '#7F7F7F' + +PRIVILEGED_NODE_COLOR = '#FF0000' +WAITING_NODE_COLOR = '#FFFF00' +NODE_COLOR = '#00FF00' + +drawnGraphNodeColors = [] +drawnGraphNodeClockValues = [] + + +class COMMAND(Enum): + DRAW = "draw" + REQUEST = "request" + HELP = "help" + SET = "set" + GET = "get" + + +class ARGUMENT(Enum): + ALL = "-all" + TIME = "-time" + REQUEST = "-request" + REPLY = "-reply" + PRIVILEGE = "-privilege" + FORWARDED = "-forwarded" + MEAN = "-mean" + +def processUserCommand(userInput: str): + try: + splitInput = userInput.split() + cmd = splitInput[0] + args = [] + if len(splitInput) > 1: + args = splitInput[1:] + + if cmd == COMMAND.REQUEST.value: + requestCommand(args) + elif cmd == COMMAND.DRAW.value: + drawCommand(args) + elif cmd == COMMAND.SET.value: + setCommand(args) + elif cmd == COMMAND.GET.value: + getCommand(args) + elif cmd == COMMAND.HELP.value: + helpCommand() + else: + print(f"Unknown input: \'{userInput}\'") + except IndexError: + pass + +def helpCommand(cmd=COMMAND.HELP): + if cmd is COMMAND.REQUEST: + print(f"Request:\n" + f"\t\"{COMMAND.REQUEST.value} nodeId\"\n" + f"\t\"{COMMAND.REQUEST.value} nodeId1 nodeId2...\"\n" + f"\t\"{COMMAND.REQUEST.value} {ARGUMENT.ALL.value}\"") + elif cmd is COMMAND.DRAW: + print(f"Draw:\n" + f"\t\"{COMMAND.DRAW.value}\"") + elif cmd is COMMAND.SET: + print(f"Set:\n" + f"\t\"{COMMAND.SET.value} {ARGUMENT.TIME.value} t\"") + elif cmd is COMMAND.GET: + print(f"Get:\n" + f"\t\"{COMMAND.GET.value} {ARGUMENT.TIME.value}\"\n" + f"\t\"{COMMAND.GET.value} {ARGUMENT.ALL.value}\"\n" + f"\t\"{COMMAND.GET.value} {ARGUMENT.ALL.value} nodeId\"\n" + f"\t\"{COMMAND.GET.value} {ARGUMENT.ALL.value} [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}]\"\n" + f"\t\"{COMMAND.GET.value} [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}] nodeId\"\n" + f"\t\"{COMMAND.GET.value} {ARGUMENT.MEAN.value}\"\n" + f"\t\"{COMMAND.GET.value} {ARGUMENT.MEAN.value} [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}]\"") + else: + helpCommand(COMMAND.REQUEST) + helpCommand(COMMAND.DRAW) + helpCommand(COMMAND.SET) + helpCommand(COMMAND.GET) + +def requestCommand(args): + allNodes = ARGUMENT.ALL.value in args + if allNodes: + args.remove(ARGUMENT.ALL.value) + + if len(args) == 0: + for nodeID in Topology().nodes: + Topology().nodes[nodeID].send_request() + else: + helpCommand(COMMAND.REQUEST) + else: + nodes = list() + for arg in args: + try: + nodeID = int(arg) + node = Topology().nodes[nodeID] + nodes.append(node) + except KeyError: + print(f"Node {nodeID} does not exist in the topology.") + except ValueError: + print(f"\'{arg}\' is not integer.") + + if nodes: + for node in nodes: + node.send_request() + else: + helpCommand(COMMAND.REQUEST) + +def drawCommand(args): + if len(args) == 0: + drawGraph(True) + else: + helpCommand(COMMAND.DRAW) + +def setCommand(args): + if len(args) == 2: + setTime = ARGUMENT.TIME.value in args + + if setTime: + args.remove(ARGUMENT.TIME.value) + try: + t = float(args[0]) + if t > 0: + RicartAgrawalaNode.privilegeSleepAmount = t + else: + print(f"Sleep time cannot be set to {t}, choose a value above 0!") + except ValueError: + print(f"\'{args[0]}\' is not float.") + else: + helpCommand(COMMAND.SET) + +def getNodeInformation(node: RicartAgrawalaNode, request=True, reply=True, privilege=True, forwarded=True): + information = [] + + if request: + information.append(f"ReceivedRequests: {node.receivedRequestCount}") + information.append(f"SentRequests: {node.sentRequestCount}") + if reply: + information.append(f"ReceivedReplies: {node.receivedReplyCount}") + information.append(f"SentReplies: {node.sentReplyCount}") + if privilege: + information.append(f"Privileged: {node.privilegeCount}") + if forwarded: + information.append(f"ForwardedMessages: {node.forwardedMessageCount}") + + return f"{node.componentinstancenumber} => " + " | ".join(information) + +def getCommand(args): + isTime = ARGUMENT.TIME.value in args + + isAll = ARGUMENT.ALL.value in args + isMean = ARGUMENT.MEAN.value in args + + isRequest = ARGUMENT.REQUEST.value in args + isReply = ARGUMENT.REPLY.value in args + isPrivilege = ARGUMENT.PRIVILEGE.value in args + isForwarded = ARGUMENT.FORWARDED.value in args + areAnyOtherArgumentsSet = isRequest or isReply or isPrivilege or isForwarded + + if isTime: + args.remove(ARGUMENT.TIME.value) + if isAll: + args.remove(ARGUMENT.ALL.value) + if isMean: + args.remove(ARGUMENT.MEAN.value) + if isRequest: + args.remove(ARGUMENT.REQUEST.value) + if isReply: + args.remove(ARGUMENT.REPLY.value) + if isPrivilege: + args.remove(ARGUMENT.PRIVILEGE.value) + if isForwarded: + args.remove(ARGUMENT.FORWARDED.value) + + if isTime and not isAll and not isMean: + if len(args) == 0 and not areAnyOtherArgumentsSet: + print(f"Sleep amount in critical section is {RicartAgrawalaNode.privilegeSleepAmount} seconds.") + else: + helpCommand(COMMAND.GET) + elif isAll and not isTime and not isMean: + if not areAnyOtherArgumentsSet: + isRequest = isReply = isPrivilege = isForwarded = True + + if len(args) == 0: + for nodeID in Topology().nodes: + node = Topology().nodes[nodeID] + print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) + else: + helpCommand(COMMAND.GET) + elif isMean and not isTime and not isAll: + if not areAnyOtherArgumentsSet: + isRequest = isReply = isPrivilege = isForwarded = True + + if len(args) == 0: + N = len(Topology().nodes) + node = RicartAgrawalaNode("", f"Mean of {N} Nodes") + + for nodeID in Topology().nodes: + node.privilegeCount += Topology().nodes[nodeID].privilegeCount + node.sentRequestCount += Topology().nodes[nodeID].sentRequestCount + node.sentReplyCount += Topology().nodes[nodeID].sentReplyCount + node.receivedRequestCount += Topology().nodes[nodeID].receivedRequestCount + node.receivedReplyCount += Topology().nodes[nodeID].receivedReplyCount + node.forwardedMessageCount += Topology().nodes[nodeID].forwardedMessageCount + + node.privilegeCount /= N + node.sentRequestCount /= N + node.sentReplyCount /= N + node.receivedRequestCount /= N + node.receivedReplyCount /= N + node.forwardedMessageCount /= N + + print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) + else: + helpCommand(COMMAND.GET) + else: + if areAnyOtherArgumentsSet and not isTime and not isAll and not isMean: + if len(args) == 1: + try: + nodeID = int(args[0]) + node = Topology().nodes[nodeID] + print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) + except KeyError: + print(f"Node {nodeID} does not exist in the topology.") + except ValueError: + print(f"\'{args[0]}\' is not integer.") + else: + helpCommand(COMMAND.GET) + else: + helpCommand(COMMAND.GET) + +def drawGraph(overwrite=False): + global drawnGraphNodeColors, drawnGraphNodeClockValues + + G = Topology().G + pos = nx.circular_layout(G, center=(0, 0)) + + nodeColors = [] + clockValues = [] + for nodeID in Topology().nodes: + node = Topology().nodes[nodeID] + G.nodes[nodeID]['clock'] = node.clock + clockValues.append(node.clock) + + if node.isPrivileged: + nodeColors.append(PRIVILEGED_NODE_COLOR) + elif node.havePendingRequest: + nodeColors.append(WAITING_NODE_COLOR) + else: + nodeColors.append(NODE_COLOR) + + if overwrite or nodeColors != drawnGraphNodeColors or clockValues != drawnGraphNodeClockValues: + drawnGraphNodeColors = list(nodeColors) + drawnGraphNodeClockValues = list(clockValues) + + clockLabelsPos = {} + for key in pos: + x, y = pos[key] + r = math.sqrt(x**2 + y**2) + theta = atan2(y, x) + radians(75) + d = 0.1 + clockLabelsPos[key] = (x + d * cos(theta), y + d * sin(theta)) + + nodeClockLabels = nx.get_node_attributes(G, 'clock') + nx.draw(G, pos, node_color=nodeColors, edge_color=EDGE_COLOR, with_labels=True, font_weight='bold') + nx.draw_networkx_labels(G, clockLabelsPos, nodeClockLabels) + + plt.draw() + plt.show() + +def graphDrawingDaemon(): + while True: + drawGraph() + sleep(1.0/FPS) + +def completeBinomialGraph(n, p): + if p <= 0: + G = nx.empty_graph(n) + elif p >= 1: + G = nx.complete_graph(n) + else: + allEdges = list(combinations(range(n), 2)) + G = nx.empty_graph(n) + + for node, nodeEdges in groupby(allEdges, key=lambda x: x[0]): + nodeEdges = list(nodeEdges) + randomEdge = random.choice(nodeEdges) + G.add_edge(*randomEdge) + for edge in nodeEdges: + if random.random() < p: + G.add_edge(*edge) + + return G + +def main(): + G = completeBinomialGraph(20, 1.000001) + + topology = Topology() + topology.construct_from_graph(G, RicartAgrawalaNode, P2PFIFOPerfectChannel) + topology.start() + + graphDaemon = threading.Thread(target=graphDrawingDaemon, daemon=True) + graphDaemon.start() + + while True: + userInput = input("User Command: \n") + processUserCommand(userInput) + + +if __name__ == "__main__": + main() -- GitLab From 5a9bc6d442e9279f78290c43279b3758934c49d8 Mon Sep 17 00:00:00 2001 From: berkeracir Date: Tue, 18 May 2021 12:21:40 +0300 Subject: [PATCH 3/4] add 'get -total' method --- tests/MutualExclusion/testRicartAgrawala.py | 36 +++++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/tests/MutualExclusion/testRicartAgrawala.py b/tests/MutualExclusion/testRicartAgrawala.py index fc1a7e5..a75df33 100644 --- a/tests/MutualExclusion/testRicartAgrawala.py +++ b/tests/MutualExclusion/testRicartAgrawala.py @@ -41,6 +41,7 @@ class ARGUMENT(Enum): PRIVILEGE = "-privilege" FORWARDED = "-forwarded" MEAN = "-mean" + TOTAL = "-total" def processUserCommand(userInput: str): try: @@ -84,8 +85,8 @@ def helpCommand(cmd=COMMAND.HELP): f"\t\"{COMMAND.GET.value} {ARGUMENT.ALL.value} nodeId\"\n" f"\t\"{COMMAND.GET.value} {ARGUMENT.ALL.value} [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}]\"\n" f"\t\"{COMMAND.GET.value} [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}] nodeId\"\n" - f"\t\"{COMMAND.GET.value} {ARGUMENT.MEAN.value}\"\n" - f"\t\"{COMMAND.GET.value} {ARGUMENT.MEAN.value} [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}]\"") + f"\t\"{COMMAND.GET.value} [{ARGUMENT.MEAN.value}/{ARGUMENT.TOTAL.value}]\"\n" + f"\t\"{COMMAND.GET.value} [{ARGUMENT.MEAN.value}/{ARGUMENT.TOTAL.value}] [{ARGUMENT.REQUEST.value}/{ARGUMENT.REPLY.value}/{ARGUMENT.PRIVILEGE.value}/{ARGUMENT.FORWARDED.value}]\"") else: helpCommand(COMMAND.REQUEST) helpCommand(COMMAND.DRAW) @@ -164,6 +165,7 @@ def getCommand(args): isAll = ARGUMENT.ALL.value in args isMean = ARGUMENT.MEAN.value in args + isTotal = ARGUMENT.TOTAL.value in args isRequest = ARGUMENT.REQUEST.value in args isReply = ARGUMENT.REPLY.value in args @@ -177,6 +179,8 @@ def getCommand(args): args.remove(ARGUMENT.ALL.value) if isMean: args.remove(ARGUMENT.MEAN.value) + if isTotal: + args.remove(ARGUMENT.TOTAL.value) if isRequest: args.remove(ARGUMENT.REQUEST.value) if isReply: @@ -186,12 +190,12 @@ def getCommand(args): if isForwarded: args.remove(ARGUMENT.FORWARDED.value) - if isTime and not isAll and not isMean: + if isTime and not isAll and not (isMean or isTotal): if len(args) == 0 and not areAnyOtherArgumentsSet: print(f"Sleep amount in critical section is {RicartAgrawalaNode.privilegeSleepAmount} seconds.") else: helpCommand(COMMAND.GET) - elif isAll and not isTime and not isMean: + elif isAll and not isTime and not (isMean or isTotal): if not areAnyOtherArgumentsSet: isRequest = isReply = isPrivilege = isForwarded = True @@ -201,13 +205,13 @@ def getCommand(args): print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) else: helpCommand(COMMAND.GET) - elif isMean and not isTime and not isAll: + elif (isMean or isTotal) and not isTime and not isAll: if not areAnyOtherArgumentsSet: isRequest = isReply = isPrivilege = isForwarded = True if len(args) == 0: N = len(Topology().nodes) - node = RicartAgrawalaNode("", f"Mean of {N} Nodes") + node = RicartAgrawalaNode("node", -1) for nodeID in Topology().nodes: node.privilegeCount += Topology().nodes[nodeID].privilegeCount @@ -217,14 +221,18 @@ def getCommand(args): node.receivedReplyCount += Topology().nodes[nodeID].receivedReplyCount node.forwardedMessageCount += Topology().nodes[nodeID].forwardedMessageCount - node.privilegeCount /= N - node.sentRequestCount /= N - node.sentReplyCount /= N - node.receivedRequestCount /= N - node.receivedReplyCount /= N - node.forwardedMessageCount /= N - - print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) + if isTotal: + node.componentinstancenumber = f"Total of {N} Nodes" + print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) + if isMean: + node.componentinstancenumber = f"Mean of {N} Nodes" + node.privilegeCount /= N + node.sentRequestCount /= N + node.sentReplyCount /= N + node.receivedRequestCount /= N + node.receivedReplyCount /= N + node.forwardedMessageCount /= N + print(getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) else: helpCommand(COMMAND.GET) else: -- GitLab From 32534d6e1e4a0bd6e15f86783dca9c30125c4079 Mon Sep 17 00:00:00 2001 From: berkeracir Date: Tue, 18 May 2021 13:26:09 +0300 Subject: [PATCH 4/4] add seed values for creating consistent graphs --- tests/MutualExclusion/testRicartAgrawala.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/MutualExclusion/testRicartAgrawala.py b/tests/MutualExclusion/testRicartAgrawala.py index a75df33..dc78674 100644 --- a/tests/MutualExclusion/testRicartAgrawala.py +++ b/tests/MutualExclusion/testRicartAgrawala.py @@ -295,7 +295,10 @@ def graphDrawingDaemon(): drawGraph() sleep(1.0/FPS) -def completeBinomialGraph(n, p): +def completeBinomialGraph(n, p, seed=None): + if seed is not None: + random.seed(seed) + if p <= 0: G = nx.empty_graph(n) elif p >= 1: @@ -312,10 +315,13 @@ def completeBinomialGraph(n, p): if random.random() < p: G.add_edge(*edge) + if seed is not None: + random.seed() + return G def main(): - G = completeBinomialGraph(20, 1.000001) + G = completeBinomialGraph(20, 0.00000001, seed=5) topology = Topology() topology.construct_from_graph(G, RicartAgrawalaNode, P2PFIFOPerfectChannel) -- GitLab