This repository has been archived on 2023-07-12. You can view files and clone it, but cannot push or open issues or pull requests.
teleschmom/main.py
2022-01-31 20:11:41 +01:00

176 lines
4.2 KiB
Python

import csv
import signal
import time
import threading
import ping3
class Ping(threading.Thread):
def __init__(self, ip: str):
super().__init__()
self._start: int = None
self._end: int = None
self._ping: int = None
self.ip = ip
def run(self) -> None:
self._start = time.time_ns() / 1_000_000
self._ping = ping3.ping(self.ip, timeout=60, unit="ms") or -1
self._end = time.time_ns() / 1_000_000
def load(self) -> (int, int, int):
self.join()
return self._start, self._end, self._ping
class PingRequester(threading.Thread):
def __init__(self, ip: str, file: str):
super().__init__()
self.stop = False
self.lock = threading.Lock()
self.event = threading.Event()
self.write_interval = 100
self.ip = ip
self.list: [Ping] = []
self.file = open(file, 'a+')
self.writer = csv.writer(self.file)
def run(self) -> None:
while not self.stop:
threading.Thread(target=self._ping).start()
time.sleep(1)
data = []
for req in self.list:
data.append(req.load())
self._write(data)
def finish(self) -> None:
self.stop = True
def _ping(self) -> None:
self.lock.acquire()
request = Ping(self.ip)
request.start()
self.list.append(request)
if len(self.list) >= self.write_interval and not self.event.is_set():
self.event.set()
self.lock.release()
data = []
for req in self.list[:self.write_interval]:
data.append(req.load())
self.list = self.list[self.write_interval:]
self._write(data)
self.event.clear()
else:
self.lock.release()
def _write(self, data: [(int, int, int)]) -> None:
self.writer.writerows(data)
self.file.flush()
class BulkPing:
def __init__(self, file: str, *ips: str):
self.ips = ips
self.event = threading.Event()
self.write_interval = 100
self.list: [[Ping]] = [[] for _ in range(len(ips))]
self.stop = False
self.file = open(file, 'a+')
self.writer = csv.writer(self.file)
def start(self) -> None:
while not self.stop:
for i, ip in enumerate(self.ips):
ping = Ping(ip)
ping.start()
self.list[i].append(ping)
if not self.event.is_set() and all(len(pings) >= self.write_interval for pings in self.list):
self.event.set()
threading.Thread(target=self._write_cached_pings).start()
time.sleep(1)
def finish(self) -> None:
self.stop = True
def _write_cached_pings(self) -> None:
rows = []
for i in range(self.write_interval):
data = []
for pings in self.list:
data.append(pings[i].load()[2])
rows.append(data)
for i in range(len(self.list)):
self.list[i] = self.list[i][self.write_interval:]
self._write(rows)
self.event.clear()
def _write(self, rows: [[int]]):
self.writer.writerows(rows)
self.file.flush()
def v1():
threads = [
PingRequester('1.1.1.1', 'data/1-1-1-1.csv'),
PingRequester('217.237.148.22', 'data/217-237-148-22.csv'),
PingRequester('192.168.2.1', 'data/192-168-2-1.csv')
]
sig_received = False
def stop(sig, frame):
if sig_received:
exit(1)
print("Stopping threads gratefully (may take up to 60 seconds)")
for thread in threads:
thread.finish()
signal.signal(signal.SIGINT, stop)
for i, thread in enumerate(threads):
thread.start()
print(f'Started thread {i}')
for thread in threads:
thread.join()
def v2():
ping = BulkPing('data/all.csv',
'1.1.1.1', '217.237.148.22', '192.168.2.1')
def stop(sig, frame):
if ping.stop:
exit(1)
print("Stopping process gratefully (may take up to 60 seconds)")
ping.finish()
signal.signal(signal.SIGINT, stop)
ping.start()
if __name__ == '__main__':
v2()