Проблема не так проста, как кажется. В идеале пакет pythonping предоставляет некоторый многоцелевой API, но это не так (в 2020 году в апреле). К сожалению, пакет pythonping также не является потокобезопасным, поэтому вы не можете go использовать пул потоков (и вы не можете использовать asyncio, как предлагается, потому что pythonping не поддерживает asyn c). Если вы выберете источник , вы увидите, что он просто проверяет пакеты ICMP и не может дифференцироваться по цели.
while time_left > 0:
# Keep listening until a packet arrives
raw_packet, source_socket, time_left = self.socket.receive(time_left)
# If we actually received something
if raw_packet != b'':
response.unpack(raw_packet)
# Ensure we have not unpacked the packet we sent (RHEL will also listen to outgoing packets)
if response.id == packet_id and response.message_type != icmp.Types.EchoRequest.type_id:
return Response(Message('', response, source_socket[0]), timeout-time_left)
Если мы отправим 10 пакетов, первый ответ подтвердит все цели. Не круто.
То, что осталось, - это пул процессов. Если мы действительно хотим использовать asyn c api примерно так:
import datetime
import asyncio
import concurrent.futures
import pythonping
# python 3.6 we had had to do this:
loop = asyncio.get_event_loop()
vpnClients = [
{'virtualAddress': '192.168.111.113'},
{'virtualAddress': '192.168.111.1'},
{'virtualAddress': '192.168.111.100'},
]
def myping(client):
target = client['virtualAddress']
res = pythonping.ping(target, count=2, timeout=2)
return { "measurement": "ping", "tags": { "virtual ip": target}, "time": datetime.datetime.utcnow(), "fields": { "min": float(res.rtt_min_ms), "max": float(res.rtt_max_ms), "avg": float(res.rtt_avg_ms) }}
async def main():
with concurrent.futures.ProcessPoolExecutor(max_workers=4) as pool:
executors = [loop.run_in_executor(pool, myping, c) for c in vpnClients]
result = await asyncio.gather(*executors)
print(result)
# You could do this if you would have python 3.7
# asyncio.run(main())
# but for 3.6, we must:
loop.run_until_complete(main())
Мы должны использовать пользовательскую функцию myping
, потому что функции-исполнители пула процессов должны возвращать выбираемые объекты отсюда ResponseList Pythonping не будет работать. Диктовка, которую вы используете, очень хороша (она может быть разборчивой).
Конечно, вы можете просто использовать многопроцессорный API.
Однако, если ваша сеть стабильна и быстра (виртуальные хосты?), Может быть лучше сократить время ожидания до чего-то небольшого.
pythonping.ping(target, count=2, timeout=0.1)