Example #1
0
 def on_message_from_bottom(self, eventobj: Event):
   self.recvcnt = self.recvcnt + 1
   self.sentcnt = eventobj.eventcontent.payload
   print(f"{self.recvcnt / self.sentcnt}")
   # print(nx.adjacency_matrix(Topology().G).todense())
   # print("Progress {:2.2}".format(self.recvcnt/self.sentcnt), end="\r")
   Topology().shortest_path_to_all(self.componentinstancenumber)
Example #2
0
def main():
    n = int(sys.argv[1])
    print(f"Creating a tree with size {n}")
    G = nx.random_tree(n)

    update = threading.Event()
    draw_delay = threading.Event()
    plt.ion()
    fig = plt.figure(num=0)

    topology = Topology()
    topology.construct_from_graph(G, FireWireNode, P2PFIFOPerfectChannel)
    topology.start()

    FireWireNode.callback = update
    FireWireNode.draw_delay = draw_delay

    while True:
        update.wait()
        node_colours = list()

        G = Topology().G
        pos = nx.spectral_layout(G, center=(0, 0))

        for nodeID in Topology().nodes:
            node = Topology().nodes[nodeID]

            if node.is_leader:
                node_colours.append(LEADER_NODE_COLOUR)
            elif node.in_root_contention:
                node_colours.append(CONTENDING_NODE_COLOUR)
            elif node.is_terminated:
                node_colours.append(PASSIVE_NODE_COLOUR)
            elif not node.is_terminated:
                node_colours.append(ACTIVE_NODE_COLOUR)

        nx.draw(
            G,
            pos,
            node_color=node_colours,
            edge_color=EDGE_COLOUR,
            with_labels=True,
            font_weight="bold",
        )

        fig.canvas.draw()
        fig.canvas.flush_events()
        fig.clear()
        update.clear()
        draw_delay.set()
        sleep(1.0 / FPS)
Example #3
0
    def on_init(self, eventobj: Event):
        sleep(1)
        self.neighbours = set(Topology().get_neighbors(
            self.componentinstancenumber))
        print(
            f"the neighbours of {self.componentinstancenumber} is {self.neighbours}"
        )

        self.send_parent_req()
Example #4
0
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()
Example #5
0
 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))
Example #6
0
def main():
    topo = Topology()
    topo.construct_single_node(Node, 0)
    topo.start()

    while True:
        pass
Example #7
0
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 on_message_from_top(self, eventobj: Event):
   # Encapsulate the SDU in network layer PDU
   applmsg = eventobj.eventcontent
   destination = applmsg.header.messageto
   nexthop = Topology().get_next_hop(self.componentinstancenumber, destination)
   if nexthop != float('inf'):
     print(f"{self.componentinstancenumber} will SEND a message to {destination} over {nexthop}")
     hdr = NetworkLayerMessageHeader(NetworkLayerMessageTypes.NETMSG, self.componentinstancenumber, destination,
                                     nexthop)
     payload = eventobj.eventcontent
     msg = GenericMessage(hdr, payload)
     self.send_down(Event(self, EventTypes.MFRT, msg))
   else:
     print(f"NO PATH: {self.componentinstancenumber} will NOTSEND a message to {destination} over {nexthop}")
Example #9
0
    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))
Example #10
0
def main():
    # G = nx.Graph()
    # G.add_nodes_from([1, 2])
    # G.add_edges_from([(1, 2)])
    # nx.draw(G, with_labels=True, font_weight='bold')
    # plt.draw()
    G = nx.random_geometric_graph(19, 0.5)
    topo = Topology()
    topo.construct_from_graph(G, AdHocNode, P2PFIFOFairLossChannel)
    for ch in topo.channels:
        topo.channels[ch].setPacketLossProbability(random.random())
        topo.channels[ch].setAverageNumberOfDuplicates(0)

    ComponentRegistry().print_components()

    topo.start()
    topo.plot()
    plt.show()  # while (True): pass

    print(topo.nodecolors)
Example #11
0
def main():
    G = completeBinomialGraph(20, 0.00000001, seed=5)

    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)
Example #12
0
def main():
  topo = Topology()

  topo.construct_sender_receiver(Sender, Receiver, P2PFIFOFairLossChannel)
  nx.draw(topo.G, with_labels=True, font_weight='bold')
  plt.draw()
  topo.channels["0-1"].setPacketLossProbability(0.1)
  topo.channels["0-1"].setAverageNumberOfDuplicates(0)

  # topo.computeForwardingTable()

  topo.start()
  plt.show()
Example #13
0
def main():
    G = nx.random_geometric_graph(9, 0.5, seed=5)
    nx.draw(G, with_labels=True, font_weight='bold')
    plt.draw()
    topo = Topology()
    topo.construct_from_graph(G, AdHocNode, P2PFIFOPerfectChannel)

    topo.start()
    time.sleep(1)

    random.seed(10)
    random_node: AdHocNode = topo.get_random_node()
    random_node.traverse_service.start_traverse()
    plt.show()

    while (True):
        pass
  def on_message_from_bottom(self, eventobj: Event):
    msg = eventobj.eventcontent
    hdr = msg.header
    payload = msg.payload

    if hdr.messageto == self.componentinstancenumber or hdr.messageto == MessageDestinationIdentifiers.NETWORKLAYERBROADCAST:  # Add if broadcast....
      self.send_up(Event(self, EventTypes.MFRB, payload))
      print(f"I received a message to {hdr.messageto} and I am {self.componentinstancenumber}")
    else:
      destination = hdr.messageto
      nexthop = Topology().get_next_hop(self.componentinstancenumber, destination)
      if nexthop != float('inf'):
        newhdr = NetworkLayerMessageHeader(NetworkLayerMessageTypes.NETMSG, self.componentinstancenumber, destination,
                                           nexthop)
        newpayload = eventobj.eventcontent.payload
        msg = GenericMessage(newhdr, newpayload)
        self.send_down(Event(self, EventTypes.MFRT, msg))
        print(f"{self.componentinstancenumber} will FORWARD a message to {destination} over {nexthop}")
      else:
        print(f"NO PATH {self.componentinstancenumber} will NOT FORWARD a message to {destination} over {nexthop}")
Example #15
0
def main():
    # G = nx.Graph()
    # G.add_nodes_from([1, 2])
    # G.add_edges_from([(1, 2)])
    # nx.draw(G, with_labels=True, font_weight='bold')
    # plt.draw()
    G = nx.random_geometric_graph(19, 0.5)
    nx.draw(G, with_labels=True, font_weight='bold')
    plt.draw()

    topo = Topology()
    topo.construct_from_graph(G, AdHocNode, P2PFIFOPerfectChannel)
    topo.start()

    plt.show()  # while (True): pass
Example #16
0
    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))
Example #17
0
 def on_init(self, eventobj: Event):
     self.otherNodeIDs = set(Topology().nodes.keys())
     self.otherNodeIDs.remove(self.componentinstancenumber)
Example #18
0
def getCommand(args):
    isTime = ARGUMENT.TIME.value in 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
    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 isTotal:
        args.remove(ARGUMENT.TOTAL.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 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 or isTotal):
        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 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("node", -1)

            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

            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:
        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)
Example #19
0
 def update_topology(self):
     Topology().nodecolors[self.componentinstancenumber] = 'r'
     Topology().plot()
Example #20
0
def run_dijkstra_scholten_simulation(args):
    ts = dt.now().timestamp()

    if args.network_type == "erg":
        N = ERG(args.node_count, args.node_connectivity)
        total_nodes = args.node_count
    elif args.network_type == "grid":
        N = Grid(args.node_count_on_edge)
        total_nodes = args.node_count_on_edge**2
    elif args.network_type == "star":
        N = Star(args.slave_count, master_is_root=args.master_is_root)
        total_nodes = args.slave_count + 1

    if args.save_tick_plots:
        tick_plots_save_path = f"{args.tick_plots_save_dir}/DS_{args.network_type}_{total_nodes}_{ts}/"
        os.mkdir(tick_plots_save_path)

        print(f"++ Tick plots will be saved to: {tick_plots_save_path}")

    if args.run_until_termination:
        args.simulation_ticks = 10**10

    assert args.hard_stop_max_tick < args.simulation_ticks
    assert args.hard_stop_min_tick > 0

    hard_stop_on_tick = None

    if args.hard_stop_nodes:
        hard_stop_on_tick = [
            random.randint(args.hard_stop_min_tick, args.hard_stop_max_tick)
            for _ in range(total_nodes)
        ]

    node_active_ticks_initial = [
        random.randint(args.node_min_activeness_after_receive,
                       args.node_max_activeness_after_receive)
        if random.random() <= args.node_initial_activeness_prob else 0
        for _ in range(total_nodes)
    ]
    alive_nodes = list(range(total_nodes))

    topo_context = {
        "network": N,
        "ms_per_tick": args.ms_per_tick,
        "simulation_ticks": args.simulation_ticks,
        "initial_liveness": node_active_ticks_initial,
        "communication_on_active_prob":
        args.node_activeness_communication_prob,
        "min_activeness_after_receive": args.node_min_activeness_after_receive,
        "max_activeness_after_receive": args.node_max_activeness_after_receive,
        "node_package_process_per_tick": args.node_package_process_per_tick,
        "passiveness_death_thresh": args.passiveness_death_thresh,
        "hard_stop_on_tick": hard_stop_on_tick,
        "alive_nodes": alive_nodes,
        "only_root_alive_initially": args.only_root_alive_initially
    }

    print(topo_context)

    topo = Topology()
    topo.construct_from_graph(N.G,
                              DijkstraScholtenAdHocNode,
                              P2PFIFOPerfectChannel,
                              context=topo_context)

    topo.start()

    stats = {
        "df":
        pd.DataFrame(
            data={
                "dead_nodes": [],
                "active_nodes": [],
                "packets_in_transmit": [],
                "queued_packets": [],
                "control_packets_sent": [],
                "control_basic_instant_ratio": [],
                "control_total_cumulative_ratio": [],
            }),
        "terminated_on_tick":
        None,
        "announced_on_tick":
        None
    }

    graphs = []

    fig, axes = plt.subplots(2, 3)
    fig.set_figwidth(25)
    fig.set_figheight(10)
    # fig.tight_layout()

    input("\n>>> Proceed ?")

    term_wait_ctr = 0
    reason = None

    try:
        for t in range(1, args.simulation_ticks + 1):
            print(f"[S] Tick: {t}")

            packages_sent = 0
            packages_waiting_on_queue = 0
            num_nodes_active = 0
            num_dead_nodes = 0
            break_this_tick = False
            control_packets_sent = 0

            T = nx.Graph()
            node_color = []

            for index, node in topo.nodes.items():
                new_state, pkg_sent_to_friend, cps = node.simulation_tick()

                if N.root == index:
                    node_color.append("red")
                elif new_state == DSAHCNodeSimulationStatus.ACTIVE:
                    node_color.append("green")
                elif new_state == DSAHCNodeSimulationStatus.PASSIVE:
                    node_color.append("mediumslateblue")
                elif new_state == DSAHCNodeSimulationStatus.OUT_OF_TREE:
                    node_color.append("gray")

                if index not in T.nodes():
                    T.add_node(index)

                if node.parent_node is not None:
                    if node.parent_node not in T.nodes():
                        T.add_node(node.parent_node)

                    T.add_edge(index, node.parent_node)

                if index == N.root and new_state is None:
                    reason = f"root terminated ({t})"
                    break_this_tick = True

                if new_state == DSAHCNodeSimulationStatus.ACTIVE:
                    num_nodes_active += 1
                elif new_state == DSAHCNodeSimulationStatus.OUT_OF_TREE:
                    num_dead_nodes += 1

                if pkg_sent_to_friend is not None:
                    packages_sent += 1

                control_packets_sent += cps
                packages_waiting_on_queue += node.waiting_packages_on_queue

            print(
                f"   (ACTIVE: {num_nodes_active}, PKGS-WAIT: {packages_waiting_on_queue}, PKGS-SENT: {packages_sent})"
            )

            if (packages_waiting_on_queue == 0 and num_nodes_active == 0
                    and packages_sent == 0):
                if stats["terminated_on_tick"] is None:
                    stats["terminated_on_tick"] = t

                print("!!! TERMINATED !!!")

                term_wait_ctr += 1

                if args.wait_ticks_after_termination > 0 and term_wait_ctr > args.wait_ticks_after_termination:
                    print("!!! FORCE TERMINATED !!!")
                    reason = f"forced ({args.wait_ticks_after_termination})"
                    break_this_tick = True

                if args.exit_on_termination:
                    break_this_tick = True

            total_pkgs_sent_cum = (stats["df"]["control_packets_sent"].sum() +
                                   control_packets_sent +
                                   stats["df"]["packets_in_transmit"].sum() +
                                   packages_sent)

            stats["df"].loc[t - 1] = [
                num_dead_nodes,
                num_nodes_active,
                packages_sent,
                packages_waiting_on_queue,
                control_packets_sent,
                (control_packets_sent / packages_sent) if packages_sent > 0
                else 0,  # TODO: Fix later, find a better soln,,,
                (((stats["df"]["control_packets_sent"].sum() +
                   control_packets_sent) /
                  total_pkgs_sent_cum) if total_pkgs_sent_cum > 0 else 0) * 100
            ]

            graphs.append({
                "edges": T.edges(),
                "nodes": T.nodes(),
            })

            if not args.no_realtime_plot or args.save_tick_plots:
                axes[0][0].cla()
                axes[0][1].cla()
                axes[0][2].cla()
                axes[1][0].cla()
                axes[1][1].cla()
                axes[1][2].cla()

                axes[0][0].set_title("Active/Dead Nodes")
                axes[0][0].set_xlabel(
                    f"Simulation Ticks ({args.ms_per_tick}ms/tick)")
                axes[0][0].set_ylabel(f"Node Count")

                axes[0][1].set_title("Packets in Transmit")
                axes[0][1].set_xlabel(
                    f"Simulation Ticks ({args.ms_per_tick}ms/tick)")
                axes[0][1].set_ylabel(f"Packet Count")

                axes[1][0].set_title("Control Packet Ratio")
                axes[1][0].set_xlabel(f"CPR ({args.ms_per_tick}ms/tick)")
                axes[1][0].set_ylabel(f"CPR (control packets/total packets)")

                axes[1][1].set_title("Instant Control Packet Ratio")
                axes[1][1].set_xlabel(
                    f"Simulation Ticks ({args.ms_per_tick}ms/tick)")
                axes[1][1].set_ylabel(f"CPR (control packets/total packets)")

                sns.lineplot(data=stats["df"]["active_nodes"],
                             ax=axes[0][0],
                             color="orange",
                             legend='brief',
                             label="Active nodes")
                sns.lineplot(data=stats["df"]["dead_nodes"],
                             ax=axes[0][0],
                             color="blue",
                             legend='brief',
                             label="Dead nodes")
                sns.lineplot(data=stats["df"]["packets_in_transmit"],
                             ax=axes[0][1],
                             color="purple",
                             legend='brief',
                             label="Basic packets")
                sns.lineplot(data=stats["df"]["control_packets_sent"],
                             ax=axes[0][1],
                             color="green",
                             legend='brief',
                             label="Control packets")
                sns.lineplot(
                    data=stats["df"]["control_total_cumulative_ratio"],
                    ax=axes[1][0],
                    color="mediumslateblue")
                sns.lineplot(data=stats["df"]["control_basic_instant_ratio"],
                             ax=axes[1][1],
                             color="red")

                nx.draw(T,
                        ax=axes[0][2],
                        with_labels=True,
                        node_color=node_color)

                if args.network_type == "grid":
                    pos = {
                        i: (i // args.node_count_on_edge,
                            i % args.node_count_on_edge)
                        for i in range(total_nodes)
                    }
                    nx.draw(N.G,
                            ax=axes[1][2],
                            with_labels=True,
                            node_color=node_color,
                            pos=pos)
                else:
                    nx.draw(N.G,
                            ax=axes[1][2],
                            with_labels=True,
                            node_color=node_color)

                plt.pause(0.0005)

                if args.save_tick_plots:
                    plt.savefig(tick_plots_save_path +
                                f"{str(t).zfill(3)}.png",
                                dpi=160)

            if break_this_tick:
                break

            time.sleep(args.ms_per_tick / 1000)
    except KeyboardInterrupt:
        pass

    axes[0][0].cla()
    axes[0][1].cla()
    axes[0][2].cla()
    axes[1][0].cla()
    axes[1][1].cla()
    axes[1][2].cla()

    sns.lineplot(data=stats["df"]["active_nodes"],
                 ax=axes[0][0],
                 color="orange")
    sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue")
    sns.lineplot(data=stats["df"]["packets_in_transmit"],
                 ax=axes[0][1],
                 color="purple")
    sns.lineplot(data=stats["df"]["control_packets_sent"],
                 ax=axes[0][1],
                 color="green")
    sns.lineplot(data=stats["df"]["control_total_cumulative_ratio"],
                 ax=axes[1][0],
                 color="mediumslateblue")
    sns.lineplot(data=stats["df"]["control_basic_instant_ratio"],
                 ax=axes[1][1],
                 color="red")

    nx.draw(T, ax=axes[0][2], with_labels=True, node_color=node_color)

    if args.network_type == "grid":
        pos = {
            i: (i // args.node_count_on_edge, i % args.node_count_on_edge)
            for i in range(total_nodes)
        }
        nx.draw(N.G,
                ax=axes[1][2],
                with_labels=True,
                node_color=node_color,
                pos=pos)
    else:
        nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color)

    plt.savefig(f"simdump/DS_stats_{args.network_type}_{total_nodes}_{ts}.png",
                dpi=200)

    with open(f"simdump/DS_run_{args.network_type}_{total_nodes}_{ts}.pkl",
              "wb") as fp:
        pickle.dump(
            {
                "args": args,
                "context": topo_context,
                "stats": stats,
                "graphs": graphs
            }, fp)

    if not args.no_realtime_plot:
        plt.show()

    print(
        f"\n{reason} [{t - stats['terminated_on_tick'] if stats['terminated_on_tick'] is not None else None}]"
    )

    if args.generate_gif:
        make_gif(f"{tick_plots_save_path}/*.png", tick_plots_save_path,
                 "animation.gif", t * 20)
Example #21
0
def main():
    n = int(sys.argv[1])
    print(f"Creating a ring with size {n}")
    G = nx.cycle_graph(n)

    plt.ion()
    fig = plt.figure(num=0)

    topology = Topology()
    topology.construct_from_graph(G, ItaiRodehNode, P2PFIFOPerfectChannel)
    topology.start()
    ItaiRodehNode.ring_size = n

    update = threading.Event()
    draw_delay = threading.Event()
    ItaiRodehNode.callback = update
    ItaiRodehNode.draw_delay = draw_delay

    while True:
        update.wait()
        assumed_ids = list()
        node_colours = list()

        G = Topology().G
        pos = nx.circular_layout(G, center=(0, 0))

        for nodeID in Topology().nodes:
            node = Topology().nodes[nodeID]
            G.nodes[nodeID]["id_p"] = node.id_p
            assumed_ids.append(node.id_p)

            if node.state == State.active:
                node_colours.append(ACTIVE_NODE_COLOUR)
            elif node.state == State.passive:
                node_colours.append(PASSIVE_NODE_COLOUR)
            elif node.state == State.leader:
                node_colours.append(LEADER_NODE_COLOUR)

        node_id_label_pos = {}
        for key in pos:
            x, y = pos[key]
            theta = atan2(y, x) + radians(75)
            d = 0.1
            node_id_label_pos[key] = (x + d * cos(theta), y + d * sin(theta))

        node_id_labels = nx.get_node_attributes(G, "id_p")

        nx.draw(
            G,
            pos,
            node_color=node_colours,
            edge_color=EDGE_COLOUR,
            with_labels=False,
            font_weight="bold",
        )

        nx.draw_networkx_labels(G, node_id_label_pos, node_id_labels)

        fig.text(0.2, 0.2, f"Round: {ItaiRodehNode.global_round}")

        fig.canvas.draw()
        fig.canvas.flush_events()
        fig.clear()
        update.clear()
        draw_delay.set()
        sleep(1.0 / FPS)
Example #22
0
 def prepare_neighbor_map(self):
     neighbor_list = Topology().get_neighbors(self.componentinstancenumber)
     return [DfsNeighbor(n, False) for n in neighbor_list]
Example #23
0
def run_shavit_francez_simulation(args):
    if args.network_type == "erg":
        N = ERG(args.node_count, args.node_connectivity)
        total_nodes = args.node_count
    elif args.network_type == "grid":
        N = Grid(args.node_count_on_edge)
        total_nodes = args.node_count_on_edge ** 2
    elif args.network_type == "star":
        N = Star(args.slave_count, master_is_root=args.master_is_root)
        total_nodes = args.slave_count + 1

    if args.run_until_termination:
        args.simulation_ticks = 10**10

    assert args.hard_stop_max_tick < args.simulation_ticks
    assert args.hard_stop_min_tick > 0

    hard_stop_on_tick = None

    if args.hard_stop_nodes:
        hard_stop_on_tick = [random.randint(args.hard_stop_min_tick, args.hard_stop_max_tick) for _ in range(total_nodes)]

    node_active_ticks_initial = [random.randint(args.node_min_activeness_after_receive, args.node_max_activeness_after_receive) if random.random() <= args.node_initial_activeness_prob else 0 for _ in range(total_nodes)]
    alive_nodes = list(range(total_nodes))
    
    topo_context = {
        "network": N,
        "ms_per_tick": args.ms_per_tick,
        "simulation_ticks": args.simulation_ticks,
        "initial_liveness": node_active_ticks_initial,
        "communication_on_active_prob": args.node_activeness_communication_prob,
        "min_activeness_after_receive": args.node_min_activeness_after_receive,
        "max_activeness_after_receive": args.node_max_activeness_after_receive,
        "node_package_process_per_tick": args.node_package_process_per_tick,
        "passiveness_death_thresh": args.passiveness_death_thresh,
        "hard_stop_on_tick": hard_stop_on_tick,
        "alive_nodes": alive_nodes,
        "only_root_alive_initially": args.only_root_alive_initially
    }

    print(topo_context)
    # N.plot()
    # plt.show()

    topo = Topology()
    topo.construct_from_graph(N.G, ShavitFrancezAdHocNode, P2PFIFOPerfectChannel, context=topo_context)

    topo.start()

    stats = {
        "df": pd.DataFrame(data={
            "dead_nodes": [],
            "active_nodes": [],
            "packets_in_transmit": [],
            "queued_packets": [],
            "control_packets_sent": [],
            "control_basic_instant_ratio": [],
            "control_total_cumulative_ratio": [],
            "wave_packets_sent": [],
            "wave_basic_instant_ratio": [],
            "wave_total_cumulative_ratio": [],
            "wave_control_cumulative_ratio": []
        }),
        "terminated_on_tick": None,
        "announced_on_tick": None
    }

    fig, axes = plt.subplots(2, 3)
    fig.set_figwidth(25)
    fig.set_figheight(10)
    # fig.tight_layout()

    input("\n>>> Proceed ?")

    term_wait_ctr = 0
    reason = None
    wave_finisher = None

    try:
        for t in range(1, args.simulation_ticks + 1):
            print(f"[S] Tick: {t}")

            packages_sent = 0
            packages_waiting_on_queue = 0
            num_nodes_active = 0
            num_dead_nodes = 0
            break_this_tick = False
            control_packets_sent = 0
            wave_packets_sent = 0

            node_color = []

            for index, node in topo.nodes.items():
                new_state, pkg_sent_to_friend, cps, wps = node.simulation_tick()

                if N.root == index and new_state != SFAHCNodeSimulationStatus.OUT_OF_TREE:
                    node_color.append("red")
                elif N.root == index and new_state == SFAHCNodeSimulationStatus.OUT_OF_TREE:
                    node_color.append("orange")
                elif new_state == SFAHCNodeSimulationStatus.ACTIVE:
                    node_color.append("green")
                elif new_state == SFAHCNodeSimulationStatus.PASSIVE:
                    node_color.append("mediumslateblue")
                elif new_state == SFAHCNodeSimulationStatus.OUT_OF_TREE:
                    node_color.append("gray")
                else: # is None...
                    # It's the wave finisher!!!
                    node_color.append("yellow")
                    wave_finisher = index

                if new_state is None:
                    reason = f"wave terminated ({t}) ({wave_finisher})"
                    break_this_tick = True

                if new_state == SFAHCNodeSimulationStatus.ACTIVE:
                    num_nodes_active += 1
                elif new_state == SFAHCNodeSimulationStatus.OUT_OF_TREE:
                    num_dead_nodes += 1

                if pkg_sent_to_friend is not None:
                    packages_sent += 1

                control_packets_sent += cps
                wave_packets_sent += wps
                packages_waiting_on_queue += node.waiting_packages_on_queue

            print(f"   (ACTIVE: {num_nodes_active}, PKGS-WAIT: {packages_waiting_on_queue}, PKGS-SENT: {packages_sent})")

            if (packages_waiting_on_queue == 0 and num_nodes_active == 0 and packages_sent == 0):
                if stats["terminated_on_tick"] is None: 
                    stats["terminated_on_tick"] = t

                print("!!! TERMINATED !!!")

                term_wait_ctr += 1

                if args.wait_ticks_after_termination > 0 and term_wait_ctr > args.wait_ticks_after_termination:
                    print("!!! FORCE TERMINATED !!!")
                    reason = f"forced ({args.wait_ticks_after_termination})"
                    break_this_tick = True

                if args.exit_on_termination:
                    break_this_tick = True

            control_pkgs_sent_cum = stats["df"]["control_packets_sent"].sum() + control_packets_sent
            total_pkgs_sent_cum = (stats["df"]["control_packets_sent"].sum() + control_packets_sent + stats["df"]["packets_in_transmit"].sum() + packages_sent + stats["df"]["wave_packets_sent"].sum() + wave_packets_sent)

            stats["df"].loc[t-1] = [
                num_dead_nodes,
                num_nodes_active,
                packages_sent,
                packages_waiting_on_queue,
                control_packets_sent,
                (control_packets_sent / packages_sent) if packages_sent > 0 else 0, # TODO: Fix later, find a better soln,,,
                (((stats["df"]["control_packets_sent"].sum() + control_packets_sent) / total_pkgs_sent_cum) if total_pkgs_sent_cum > 0 else 0) * 100,
                wave_packets_sent,
                (wave_packets_sent / packages_sent) if packages_sent > 0 else 0, # TODO: Fix later, find a better soln,,,
                (((stats["df"]["wave_packets_sent"].sum() + wave_packets_sent) / total_pkgs_sent_cum) if total_pkgs_sent_cum > 0 else 0) * 100,
                (((stats["df"]["wave_packets_sent"].sum() + wave_packets_sent) / control_pkgs_sent_cum) if control_pkgs_sent_cum > 0 else 0) * 100,
            ]

            # axes.scatter(x=t, y=num_nodes_active)
            
            if not args.no_realtime_plot:
                axes[0][0].cla()
                axes[0][1].cla()
                axes[0][2].cla()
                axes[1][0].cla()
                axes[1][1].cla()
                axes[1][2].cla()

                sns.lineplot(data=stats["df"]["active_nodes"], ax=axes[0][0], color="orange")
                sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue")
                sns.lineplot(data=stats["df"]["packets_in_transmit"], ax=axes[0][1], color="purple")
                sns.lineplot(data=stats["df"]["control_packets_sent"], ax=axes[0][1], color="green")
                sns.lineplot(data=stats["df"]["wave_packets_sent"], ax=axes[0][1], color="blue")
                sns.lineplot(data=stats["df"]["control_total_cumulative_ratio"], ax=axes[1][0], color="mediumslateblue")
                sns.lineplot(data=stats["df"]["wave_total_cumulative_ratio"], ax=axes[1][0], color="yellow")
                sns.lineplot(data=stats["df"]["control_basic_instant_ratio"], ax=axes[1][1], color="red")
                sns.lineplot(data=stats["df"]["wave_basic_instant_ratio"], ax=axes[1][1], color="orange")
                sns.lineplot(data=stats["df"]["wave_control_cumulative_ratio"], ax=axes[0][2], color="mediumslateblue")
                
                if args.network_type == "grid":   
                    pos = {i: (i // args.node_count_on_edge, i % args.node_count_on_edge) for i in range(total_nodes)}
                    nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color, pos=pos)
                else:
                    nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color)

                plt.pause(0.0005)

            if break_this_tick:
                break

            time.sleep(args.ms_per_tick / 1000)
    except KeyboardInterrupt:
        pass

    ts = dt.now().timestamp()

    if args.no_realtime_plot:
        axes[0][0].cla()
        axes[0][1].cla()
        axes[0][2].cla()
        axes[1][0].cla()
        axes[1][1].cla()
        axes[1][2].cla()

        sns.lineplot(data=stats["df"]["active_nodes"], ax=axes[0][0], color="orange")
        sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue")
        sns.lineplot(data=stats["df"]["packets_in_transmit"], ax=axes[0][1], color="purple")
        sns.lineplot(data=stats["df"]["control_packets_sent"], ax=axes[0][1], color="green")
        sns.lineplot(data=stats["df"]["wave_packets_sent"], ax=axes[0][1], color="blue")
        sns.lineplot(data=stats["df"]["control_total_cumulative_ratio"], ax=axes[1][0], color="mediumslateblue")
        sns.lineplot(data=stats["df"]["wave_total_cumulative_ratio"], ax=axes[1][0], color="yellow")
        sns.lineplot(data=stats["df"]["control_basic_instant_ratio"], ax=axes[1][1], color="red")
        sns.lineplot(data=stats["df"]["wave_basic_instant_ratio"], ax=axes[1][1], color="orange")
        sns.lineplot(data=stats["df"]["wave_control_cumulative_ratio"], ax=axes[0][2], color="mediumslateblue")
        
        if args.network_type == "grid":   
            pos = {i: (i // args.node_count_on_edge, i % args.node_count_on_edge) for i in range(total_nodes)}
            nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color, pos=pos)
        else:
            nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color)

        plt.pause(0.0005)

    plt.savefig(f"simdump/SF_stats_{args.network_type}_{total_nodes}_{ts}.png", dpi=200)

    with open(f"simdump/SF_run_{args.network_type}_{total_nodes}_{ts}.pkl", "wb") as fp:
        pickle.dump({
            "args": args,
            "context": topo_context,
            "stats": stats
        }, fp)

    if not args.no_realtime_plot:
        plt.show()

    print(f"\n{reason} [{t - stats['terminated_on_tick'] if stats['terminated_on_tick'] is not None else None}]")
Example #24
0
 def prepare_neighbor_map(self):
     neighbor_list = Topology().get_neighbors(self.componentinstancenumber)
     # return [{"neighbor": n, "invoked": False} for n in neighbor_list]
     return [TarryNeighbor(n, False) for n in neighbor_list]