from collections import Iterable from .buffer import Buffer from .core import TickProcess def NodeFactory(router, **kwargs): def factory(network, nid): return Node(network, nid, router=router, **kwargs) return factory class Node(TickProcess): '''''' def __init__(self, network, nid, buffer_size=None, tick_time=1, router=None): '''''' super().__init__(tick_time) self.env = network.env self.network = network self.id = nid self.buffer = Buffer(self.env, capacity=buffer_size) if router is None: router = routers['direct'] self.router = router(self) self.start(self.env) def route_packets(self): packets_to_delete = [] for packet in self.buffer: # remove expired packets from buffer if packet.expired(self.env.now): packets_to_delete.append(packet) continue # ask the router what to do targets, reason, delete = self.router(packet) # check if there are targets to send to if targets is None: continue # allow for targets to be iterable or single item if not isinstance(targets, Iterable): targets = [targets] # send the packet self.send(targets, packet, reason) # if the router requested deletion from the buffer do it if delete: packets_to_delete.append(packet) for packet in packets_to_delete: self.buffer.remove(packet) def process(self, **kwargs): '''''' while True: yield self.tick() def send(self, targets, packet, reason): # TODO: transfer delay packet.send(self, targets, reason=reason) for target in targets: self.network.send_link(self, target, packet) def recv(self, packet): if packet.destination == self: packet.recv() else: self.buffer.add(packet) @property def community(self): return self.network.community[self] @property def links(self): ''' Returns a list of connected links. ''' links = { met: data for met, data in self.network[self].items() if data['state'] } return links def __repr__(self): return 'Node(id={})'.format(self.id)