Skip to content
Snippets Groups Projects
Commit 8a371b4a authored by Jarrod Pas's avatar Jarrod Pas
Browse files

Improves packet analytics

parent c4f3472b
No related branches found
No related tags found
1 merge request!3Version 0.2
...@@ -9,6 +9,8 @@ import simpy ...@@ -9,6 +9,8 @@ import simpy
import yaml import yaml
import networkx as nx import networkx as nx
from .core import TickProcess
from .communities import types as communities from .communities import types as communities
from .routers import types as routers from .routers import types as routers
from .traces import types as traces from .traces import types as traces
...@@ -83,7 +85,7 @@ class Network: ...@@ -83,7 +85,7 @@ class Network:
def send_link(self, a, b, packet): def send_link(self, a, b, packet):
'''''' ''''''
if self[a][b]['state']: if self.graph[a][b]['state']:
# TODO: transfer delay # TODO: transfer delay
b.recv(packet) b.recv(packet)
else: else:
...@@ -102,47 +104,47 @@ def NodeFactory(router, **kwargs): ...@@ -102,47 +104,47 @@ def NodeFactory(router, **kwargs):
return factory return factory
class Node: class Node(TickProcess):
'''''' ''''''
def __init__(self, env, network, nid, def __init__(self, env, network, nid,
buffer_size=None, tick_time=1, router=None): buffer_size=None, tick_time=1, router=None):
'''''' ''''''
super().__init__(tick_time)
self.env = env self.env = env
self.network = network self.network = network
self.id = nid self.id = nid
self.tick_time = tick_time
self.ticker = env.process(self.tick())
self.buffer = Buffer(self.env, capacity=buffer_size) self.buffer = Buffer(self.env, capacity=buffer_size)
# bind router as a class method # bind router as a class method
if router is None: if router is None:
router = routers['direct'] router = routers['direct']
self.router = router.__get__(self, Node) self.router = router #router.__get__(self, Node)
self.router_state = {} self.router_state = {}
def tick(self): self.start(env)
''''''
while True:
packets_to_delete = []
for packet in self.buffer: def route_packets(self):
if packet.ttl < self.env.now: packets_to_delete = []
packets_to_delete.append(packet)
continue
if self.router(packet, self.router_state):
packets_to_delete.append(packet)
for packet in packets_to_delete: for packet in self.buffer:
self.buffer.remove(packet) if self.router(self, packet, self.router_state):
packets_to_delete.append(packet)
yield self.env.timeout(self.tick_time) for packet in packets_to_delete:
self.buffer.remove(packet)
def send(self, to, packet): def process(self):
''''''
while True:
self.buffer.clean()
self.route_packets()
yield self.tick()
def send(self, to, packet, reason=None):
# TODO: transfer delay # TODO: transfer delay
packet.send() packet.send(self, to, reason=reason)
self.network.send_link(self, to, packet) self.network.send_link(self, to, packet)
def recv(self, packet): def recv(self, packet):
...@@ -151,6 +153,11 @@ class Node: ...@@ -151,6 +153,11 @@ class Node:
else: else:
self.buffer.add(packet) self.buffer.add(packet)
'''
def __eq__(self, other):
return self.id == other.id
'''
@property @property
def community(self): def community(self):
return self.network.community[self] return self.network.community[self]
...@@ -175,7 +182,8 @@ class Buffer: ...@@ -175,7 +182,8 @@ class Buffer:
def __init__(self, env, capacity=0): def __init__(self, env, capacity=0):
self.env = env self.env = env
if capacity <= 0:
if capacity is None or capacity <= 0:
self.capacity = float('inf') self.capacity = float('inf')
else: else:
self.capacity = capacity self.capacity = capacity
...@@ -183,6 +191,16 @@ class Buffer: ...@@ -183,6 +191,16 @@ class Buffer:
self.buffer = OrderedDict() self.buffer = OrderedDict()
self.used = 0 self.used = 0
def clean(self):
packets_to_drop = []
for packet in self:
if packet.ttl < self.env.now:
packets_to_drop.append(packet)
for packet in packets_to_drop:
self.remove(packet)
def add(self, packet): def add(self, packet):
if self.used < self.capacity: if self.used < self.capacity:
self.used += 1 self.used += 1
...@@ -216,13 +234,20 @@ class PacketGenerator(TickProcess): ...@@ -216,13 +234,20 @@ class PacketGenerator(TickProcess):
def process(self, network): def process(self, network):
packet_id = 0 packet_id = 0
yield self.env.timeout(self.start_delay) def create(packet_id):
while True:
source, dest = random.choice(network.links) source, dest = random.choice(network.links)
packet = Packet(packet_id, source, dest, packet = Packet(packet_id, source, dest,
self.env.now + self.time_to_live, None) self.env.now + self.time_to_live, None)
self.packets.append(packet) self.packets.append(packet)
source.recv(packet) source.recv(packet)
yield self.env.timeout(self.start_delay)
print('starting packets')
#@DEBUG
for i in range(217):
pass
#@DEBUG
while True:
create(packet_id)
yield self.tick() yield self.tick()
packet_id += 1 packet_id += 1
...@@ -234,6 +259,13 @@ class PacketGenerator(TickProcess): ...@@ -234,6 +259,13 @@ class PacketGenerator(TickProcess):
if packet.recieved if packet.recieved
]) ])
@property
def recieved_count(self):
return sum([
packet.recieved_count
for packet in self.packets
])
@property @property
def sent(self): def sent(self):
return sum([ return sum([
...@@ -241,16 +273,44 @@ class PacketGenerator(TickProcess): ...@@ -241,16 +273,44 @@ class PacketGenerator(TickProcess):
for packet in self.packets for packet in self.packets
]) ])
@property
def stats(self):
stats = {}
for packet in self.packets:
for stat, value in packet.stats.items():
if stat not in stats:
stats[stat] = value
else:
stats[stat] += value
return stats
@property
def paths(self):
return {
packet: packet.path
for packet in self.packets
if packet.recieved
}
@property @property
def total(self): def total(self):
return len(self.packets) return len(self.packets)
def __str__(self): def __str__(self):
return "recieved: {}, sent: {}, packets: {}".format( ret = "recieved: {}/{}, delivery ratio: {}, packets: {}, sent: {}, stats: {}, path: {}".format(
self.recieved, self.recieved,
self.recieved_count,
self.recieved / len(self.packets),
len(self.packets),
self.sent, self.sent,
self.total self.stats,
sum([ len(path) for path in self.paths.values() ]) / self.recieved
) )
'''
for packet, path in self.paths.items():
ret += '\n {}: {}'.format(packet, path)
'''
return ret
class Packet: class Packet:
def __init__(self, id, source, destination, ttl, payload): def __init__(self, id, source, destination, ttl, payload):
...@@ -260,6 +320,10 @@ class Packet: ...@@ -260,6 +320,10 @@ class Packet:
self.ttl = ttl self.ttl = ttl
self.payload = payload self.payload = payload
self.path = []
self.stats = dict()
self.sent = 0 self.sent = 0
self.recieved = False self.recieved = False
...@@ -268,7 +332,11 @@ class Packet: ...@@ -268,7 +332,11 @@ class Packet:
self.dropped = False self.dropped = False
self.dropped_count = 0 self.dropped_count = 0
def send(self): def send(self, a, b, reason=None):
if reason is None:
self.path.append((a.id, b.id))
else:
self.path.append((a.id, b.id, reason))
self.sent += 1 self.sent += 1
def drop(self): def drop(self):
...@@ -280,7 +348,7 @@ class Packet: ...@@ -280,7 +348,7 @@ class Packet:
self.recieved_count += 1 self.recieved_count += 1
def __str__(self): def __str__(self):
return "Packet(id={}, source={}, destination={})".format( return "Packet(id={}, src={}, dst={})".format(
self.id, self.id,
self.source, self.source,
self.destination self.destination
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment