This repository has been archived by the owner on Aug 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Created module sim with both the DiscreteEventSimulator class and an implementation of it in it. * Changed file structure. Added notebook for testing the code. * Added python cache and notebook folders to git ignore
- Loading branch information
1 parent
7d66b3d
commit 22e51d0
Showing
12 changed files
with
265 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 11, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"output_type": "execute_result", | ||
"data": { | ||
"text/plain": "[<HybridRole.PRIMARY: 1>, 'GOSSIP', 'Hello World!']" | ||
}, | ||
"metadata": {}, | ||
"execution_count": 11 | ||
} | ||
], | ||
"source": [ | ||
"from nodes.hybrid import HybridNode, HybridRole, MessageType\n", | ||
"\n", | ||
"node = HybridNode (0, HybridRole.PRIMARY, [])\n", | ||
"\n", | ||
"msg = (MessageType.GOSSIP, 1000, \"Hello World!\")\n", | ||
"\n", | ||
"node.handle(1, msg)\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from sim.faulty import FaultySimulator" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.7.6-final" | ||
}, | ||
"orig_nbformat": 2, | ||
"kernelspec": { | ||
"name": "python37664bitf145e88782004c4e8f08cdfdceda798c", | ||
"display_name": "Python 3.7.6 64-bit" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__all__ = ["node", "hybrid"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from .node import Node | ||
|
||
from enum import Enum | ||
|
||
class HybridNode (Node): | ||
|
||
# - id: identification number | ||
# - role: node role in the network | ||
# - neighbors: adjacent nodes id's | ||
def __init__ (self, id, role, neighbors): | ||
|
||
self.id = id | ||
self.role = role | ||
self.neighbors = neighbors | ||
|
||
|
||
def handle (self, src, data): | ||
|
||
# unpacking data | ||
type, id, payload = data | ||
|
||
# handling different types of messages | ||
if type is MessageType.GOSSIP: | ||
|
||
return self.__gossip__(src, id, payload) | ||
|
||
elif type is MessageType.IHAVE: | ||
|
||
return self.__ihave__(src, id) | ||
|
||
elif type is MessageType.ASK: | ||
|
||
return self.__ask__(src, id) | ||
|
||
elif type is MessageType.PERIODIC: | ||
|
||
return self.__periodic__(src, id) | ||
|
||
elif type is MessageType.GC: | ||
|
||
return self.__gc__(src) | ||
|
||
else: | ||
|
||
return [] | ||
|
||
|
||
def __gossip__ (self, src, id, payload): | ||
|
||
return [self.role, "GOSSIP", payload] | ||
|
||
def __ihave__ (self, src, id): | ||
|
||
return [] | ||
|
||
def __ack__ (self, src, id): | ||
|
||
return [] | ||
|
||
def __ask__ (self, src, id): | ||
|
||
return [] | ||
|
||
def __periodic__ (self, src, id): | ||
|
||
return [] | ||
|
||
def __gc__ (self, src): | ||
|
||
return [] | ||
|
||
# different types of messages recognized by this type of node | ||
class MessageType(Enum): | ||
|
||
GOSSIP = 1 | ||
IHAVE = 2 | ||
ASK = 3 | ||
PERIODIC = 4 | ||
GC = 5 | ||
ACK = 6 | ||
|
||
# different types of hybrid node | ||
class HybridRole (Enum): | ||
|
||
PRIMARY = 1 | ||
SECUNDARY = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
class Node: | ||
|
||
# returns e.g. [(dst0, msg0), (dst1, msg1), ...] | ||
def handle (self, src, data): | ||
|
||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__all__ = ["sim", "faulty"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
from .sim import DiscreteEventSimulator | ||
|
||
import random | ||
|
||
class FaultySimulator (DiscreteEventSimulator): | ||
|
||
# - nodes: graph nodes | ||
# - distances: distances between each node | ||
# - fault_chance: probability of losing a message in simulation | ||
def __init__(self, nodes, distances, fault_chance = 0): | ||
|
||
# nodes | ||
self.nodes = nodes | ||
|
||
# distances between nodes | ||
self.distances = distances | ||
|
||
# simulator current instant tracker | ||
self.current_instant = 0 | ||
|
||
# events pending execution [(instant, (src, dst, data))] | ||
self.pending = [] | ||
|
||
# probability of losing an event | ||
self.fault_chance = fault_chance | ||
|
||
def start(self, initial_data, initial_node): | ||
|
||
# starting randomizer | ||
random.seed() | ||
|
||
# creating first event [instant, (src, dst, data)] | ||
instant, src, dst, data = 0, None, initial_node, initial_data | ||
|
||
# schedule first event | ||
self.pending.append( (instant, (src, dst, data )) ) | ||
|
||
# run the loop | ||
return self.__loop__() | ||
|
||
def __loop__(self): | ||
|
||
# creating a sorted event list | ||
ordered_events = [] | ||
|
||
# running loop | ||
while len(self.pending) > 0: | ||
|
||
# getting the event with lowest instant | ||
event = min (self.pending, key = lambda e:e[0]) | ||
|
||
# unfolding event properties | ||
instant, src, dst, data = event[0], event[1][0], event[1][1], event[1][2] | ||
|
||
# printing event | ||
# print(str(instant) + "s :: " + str(src) + " -> " + str(dst) + " :: " + str(data)) | ||
|
||
# removing event from the queue | ||
self.pending.remove(event) | ||
|
||
# skipping event based on fault probability | ||
if random.random() < self.fault_chance: | ||
|
||
# skipping iteration | ||
continue | ||
|
||
# executing event if event is valid | ||
if (src, dst) in self.distances or src is None: | ||
|
||
# appending event to sorted event list | ||
ordered_events.append(event) | ||
|
||
# generating new events from event | ||
self.__exec__(event) | ||
|
||
# returning sorted event list | ||
return ordered_events | ||
|
||
def __exec__ (self, event): | ||
|
||
# unfolding event properties | ||
instant, src, dst, data = event[0], event[1][0], event[1][1], event[1][2] | ||
|
||
# node handling event and generating new datas | ||
new_datas = self.nodes[dst].handle(src, data) | ||
|
||
# update src node | ||
new_src = dst | ||
|
||
# generating events for each data | ||
for (new_dst, new_data, delay) in new_datas: | ||
|
||
# get distance to node | ||
distance = self.distances[(new_src, new_dst)] | ||
|
||
# creating new event | ||
new_event = (instant + distance + delay, (new_src, new_dst, new_data)) | ||
|
||
# appending event to pending | ||
self.pending.append(new_event) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
class DiscreteEventSimulator: | ||
|
||
# returns list of events ordered by time | ||
def start(self, initial_data, initial_node): | ||
|
||
pass |