-
Jarrod Pas authoredJarrod Pas authored
main.py 4.34 KiB
from argparse import ArgumentParser
from datetime import datetime
import random
import sys
import simpy
import yaml
from pydtn import Network, NodeFactory
from pydtn.traces import types as traces
from pydtn.routers import types as routers
from pydtn.communities import types as communities
def parse_args(args):
parser = ArgumentParser()
parser.add_argument('--seed', '-s', metavar='seed', type=int,
default=42)
parser.add_argument('--trace', '-t', metavar='type', default='random',
choices=[t for t in traces])
parser.add_argument('--trace-args', '-ta', metavar='arg', nargs='+')
parser.add_argument('--router', '-r', metavar='type', default='direct',
choices=[t for t in routers])
parser.add_argument('--router-args', '-ra', metavar='arg', nargs='+')
parser.add_argument('--community', '-c', metavar='type', default='none',
choices=[t for t in communities])
parser.add_argument('--community-args', '-ca', metavar='arg', nargs='+')
parser.add_argument('--node-args', '-na', metavar='arg', nargs='+')
parser.add_argument('--packet-args', '-pa', metavar='arg', nargs='+')
def list_to_args(args):
if args is None:
return {}
else:
args = '\n'.join(args).replace('=',': ')
return yaml.safe_load(args)
args = parser.parse_args(args)
args.trace_args = list_to_args(args.trace_args)
args.router_args = list_to_args(args.router_args)
args.community_args = list_to_args(args.community_args)
args.node_args = list_to_args(args.node_args)
args.packet_args = list_to_args(args.packet_args)
return args
class Progress:
def __init__(self, length, ticks, alpha):
self.length = length
self.alpha = alpha
self.tick = 0
self.ticks = ticks
self.average = 0
self.__start = None
self.__last_print_len = 0
@property
def bar(self):
progress = round(self.tick / self.ticks * self.length)
return '[' + '='*progress + ' '*(self.length - progress) + ']'
@property
def time(self):
remains = (self.ticks - self.tick) * self.average
ranges = [
('day', 24*60*60),
('hour', 60*60),
('minute', 60),
('second', 1),
]
for unit, weight in ranges:
if remains >= weight:
remains = round(remains / weight)
plural = 's' if remains != 1 else ''
return f'{remains} {unit}{plural}'
return '0 seconds'
def __next__(self):
now = datetime.now().timestamp()
if self.__start is not None:
dt = now - self.__start
self.average = self.average + self.alpha * (dt - self.average)
self.__start = now
self.tick += 1
if self.tick > self.ticks:
raise StopIteration
print('\r' + ' '*self.__last_print_len, end='\r')
line = f'{self.bar} {self.time} to go...'
print(line, end=' ', flush=True)
self.__last_print_len = len(line)
return self.tick
def __iter__(self):
return self
def main(args):
args = parse_args(args)
print(args)
out = {
'seed': args.seed,
'router': args.router,
'community': args.community,
}
if args.trace == 'csv':
out['trace'] = args.trace_args['path']
for k, v in out.items():
print(f'{k}: {v}')
random.seed(args.seed)
env = simpy.Environment()
trace = traces[args.trace](**args.trace_args)
router = routers[args.router]
community = communities[args.community](**args.community_args)
node_factory = NodeFactory(router, **args.node_args)
network = Network(env,
packets=args.packet_args,
node_factory=node_factory,
community=community,
trace=trace)
progress = Progress(50, 500, 0.75)
while True:
try:
for tick in progress:
until = tick / progress.ticks * trace.duration
env.run(until=until)
print(' Done!')
print(str(network.packets))
return 0
except KeyboardInterrupt:
print('\nBye!')
return 0
if __name__ == '__main__':
exit(main(sys.argv[1:]))