Some checks failed
Update Documentation / update-repos-info (push) Has been cancelled
- Capability Registry (Postgres heartbeat) - NATS Client (підписка на streams) - Job Executor (виконання jobs) - Metrics Exporter (Prometheus) - Dockerfile для deployment - Виправлено server_name в NATS (emptyDir) TODO: Реальна реалізація embed/retrieve/summarize, Matrix Gateway, Auth
114 lines
3.6 KiB
Python
114 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Worker Daemon для Memory Module
|
|
Реєстрація capabilities, підписка на NATS streams, виконання jobs
|
|
"""
|
|
|
|
import asyncio
|
|
import os
|
|
import signal
|
|
import sys
|
|
from typing import Optional
|
|
|
|
from worker.registry import CapabilityRegistry
|
|
from worker.nats_client import NATSClient
|
|
from worker.job_executor import JobExecutor
|
|
from worker.metrics import MetricsExporter
|
|
|
|
|
|
class WorkerDaemon:
|
|
def __init__(self):
|
|
self.node_id = os.getenv("NODE_ID", "unknown")
|
|
self.tier = os.getenv("TIER", "C")
|
|
self.region = os.getenv("REGION", "unknown")
|
|
self.nats_url = os.getenv("NATS_URL", "nats://nats-client.nats:4222")
|
|
self.postgres_url = os.getenv("CAPABILITY_REGISTRY", "")
|
|
|
|
self.registry: Optional[CapabilityRegistry] = None
|
|
self.nats_client: Optional[NATSClient] = None
|
|
self.job_executor: Optional[JobExecutor] = None
|
|
self.metrics: Optional[MetricsExporter] = None
|
|
|
|
self.running = False
|
|
|
|
async def start(self):
|
|
"""Запуск worker daemon"""
|
|
print(f"🚀 Worker Daemon запускається...")
|
|
print(f" Node ID: {self.node_id}")
|
|
print(f" Tier: {self.tier}")
|
|
print(f" NATS URL: {self.nats_url}")
|
|
|
|
# Ініціалізація компонентів
|
|
self.registry = CapabilityRegistry(self.postgres_url, self.node_id, self.tier, self.region)
|
|
self.nats_client = NATSClient(self.nats_url)
|
|
self.job_executor = JobExecutor(self.node_id, self.tier)
|
|
self.metrics = MetricsExporter(port=9090)
|
|
|
|
# Реєстрація capabilities
|
|
await self.registry.register()
|
|
|
|
# Підключення до NATS
|
|
await self.nats_client.connect()
|
|
|
|
# Підписка на streams
|
|
await self.nats_client.subscribe_streams(self.job_executor)
|
|
|
|
# Запуск metrics server
|
|
await self.metrics.start()
|
|
|
|
# Heartbeat loop
|
|
self.running = True
|
|
asyncio.create_task(self.heartbeat_loop())
|
|
|
|
print("✅ Worker Daemon запущено")
|
|
|
|
async def heartbeat_loop(self):
|
|
"""Heartbeat кожні 30 секунд"""
|
|
while self.running:
|
|
await asyncio.sleep(30)
|
|
if self.registry:
|
|
await self.registry.update_heartbeat()
|
|
|
|
async def stop(self):
|
|
"""Зупинка worker daemon"""
|
|
print("🛑 Зупинка Worker Daemon...")
|
|
self.running = False
|
|
|
|
if self.nats_client:
|
|
await self.nats_client.disconnect()
|
|
if self.registry:
|
|
await self.registry.unregister()
|
|
if self.metrics:
|
|
await self.metrics.stop()
|
|
|
|
print("✅ Worker Daemon зупинено")
|
|
|
|
def setup_signal_handlers(self):
|
|
"""Налаштування обробників сигналів"""
|
|
def signal_handler(sig, frame):
|
|
print(f"\n📡 Отримано сигнал {sig}")
|
|
asyncio.create_task(self.stop())
|
|
sys.exit(0)
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
|
|
async def main():
|
|
daemon = WorkerDaemon()
|
|
daemon.setup_signal_handlers()
|
|
|
|
try:
|
|
await daemon.start()
|
|
# Чекаємо поки працює
|
|
while daemon.running:
|
|
await asyncio.sleep(1)
|
|
except KeyboardInterrupt:
|
|
pass
|
|
finally:
|
|
await daemon.stop()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|