platypush/platypush/backend/ping/__init__.py

72 lines
2.4 KiB
Python

import time
from typing import List, Tuple
from platypush.backend import Backend
from platypush.context import get_plugin
from platypush.message.event.ping import HostUpEvent, HostDownEvent
from platypush.utils.workers import Worker, Workers
class PingBackend(Backend):
"""
This backend allows you to ping multiple remote hosts at regular intervals.
Triggers:
- :class:`platypush.message.event.ping.HostDownEvent` if a host stops responding ping requests
- :class:`platypush.message.event.ping.HostUpEvent` if a host starts responding ping requests
"""
class Pinger(Worker):
def __init__(self, *args, **kwargs):
self.timeout = kwargs.pop('timeout')
self.count = kwargs.pop('count')
super().__init__(*args, **kwargs)
def process(self, host: str) -> Tuple[str, bool]:
pinger = get_plugin('ping')
response = pinger.ping(host, timeout=self.timeout, count=self.count).output
return host, response['success'] is True
def __init__(self, hosts: List[str], timeout: float = 5.0, interval: float = 60.0, count: int = 1, *args, **kwargs):
"""
:param hosts: List of IP addresses or host names to monitor.
:param timeout: Ping timeout.
:param interval: Interval between two scans.
:param count: Number of pings per host. A host will be considered down
if all the ping requests fail.
"""
super().__init__(*args, **kwargs)
self.hosts = {h: None for h in hosts}
self.timeout = timeout
self.interval = interval
self.count = count
def run(self):
super().run()
self.logger.info('Starting ping backend with {} hosts to monitor'.format(len(self.hosts)))
while not self.should_stop():
workers = Workers(10, self.Pinger, timeout=self.timeout, count=self.count)
with workers:
for host in self.hosts.keys():
workers.put(host)
for response in workers.responses:
host, is_up = response
if is_up != self.hosts[host]:
if is_up:
self.bus.post(HostUpEvent(host))
else:
self.bus.post(HostDownEvent(host))
self.hosts[host] = is_up
time.sleep(self.interval)
# vim:sw=4:ts=4:et: