"""Heatbeat utils.""" import fcntl import json import time from notifications_delivery import config def send(workers): """Send heartbeat data.""" heartbeat_data = { 'timestamp': time.time(), 'workers': [] } for worker in workers: heartbeat_data['workers'].append({ 'name': worker.name, 'is_alive': worker.is_alive(), }) with open(config.HEARTBEAT_FILE, 'w') as f: fcntl.flock(f, fcntl.LOCK_EX) try: json.dump(heartbeat_data, f) finally: fcntl.flock(f, fcntl.LOCK_UN) def validate(): """Validate heartbeat data.""" try: with open(config.HEARTBEAT_FILE, 'r') as f: fcntl.flock(f, fcntl.LOCK_SH) try: data = json.load(f) if time.time() - data['timestamp'] > config.HEARTBEAT_TIMEOUT: print('Heartbeat data is stale') return False dead_workers = [ worker['name'] for worker in data['workers'] if not worker['is_alive'] ] if dead_workers: print(f'Dead workers: {", ".join(dead_workers)}') return False except (json.decoder.JSONDecodeError, KeyError, ValueError): print('Invalid heartbeat data') return False finally: fcntl.flock(f, fcntl.LOCK_UN) except FileNotFoundError: print("Can't read heartbeat data") return False return True