#!/usr/bin/python3 """ Author: Ryan Summers Description: Provides a mechanism for measuring Stabilizer stream data throughput. """ import socket import collections import struct import time import logging # Representation of a single data batch transmitted by Stabilizer. Packet = collections.namedtuple('Packet', ['index', 'data']) Format = collections.namedtuple('Format', ['sample_size_bytes', 'batch_format']) # All supported formats by this reception script. FORMAT = { 0: Format(sample_size_bytes=8, batch_format='<{batch_size}H{batch_size}H{batch_size}H{batch_size}H') } class Timer: """ A basic timer for measuring elapsed time periods. """ def __init__(self, period=1.0): """ Create the timer with the provided period. """ self.start_time = time.time() self.trigger_time = self.start_time + period self.period = period self.started = False def is_triggered(self): """ Check if the timer period has elapsed. """ now = time.time() return now >= self.trigger_time def start(self): """ Start the timer. """ self.start_time = time.time() self.started = True def is_started(self): """ Check if the timer has started. """ return self.started def arm(self): """ Arm the timer trigger. """ self.trigger_time = time.time() + self.period def elapsed(self): """ Get the elapsed time since the timer was started. """ now = time.time() return now - self.start_time class PacketParser: """ Utilize class used for parsing received UDP data. """ def __init__(self): """ Initialize the parser. """ self.buf = b'' self.total_bytes = 0 def ingress(self, data): """ Ingress received UDP data. """ self.total_bytes += len(data) self.buf += data def parse_all_packets(self): """ Parse all received packets from the receive buffer. Returns: A list of received Packets. """ packets = [] while True: new_packets = self._parse() if new_packets: packets += new_packets else: return packets def _parse(self): """ Attempt to parse packets from the received buffer. """ # Attempt to parse a block from the buffer. if len(self.buf) < 4: return None start_id, format_id, batch_count, batch_size = struct.unpack_from('