video_monitor/app/analysis/event_bridge.py

83 lines
2.3 KiB
Python
Raw Normal View History

2026-08-30 22:22:11 +08:00
"""分析事件桥 — 消费子进程 event_queue在主进程写库"""
import logging
import queue
import threading
logger = logging.getLogger("analysis.event_bridge")
_BRIDGE = None
_BRIDGE_LOCK = threading.Lock()
class AnalysisEventBridge(object):
def __init__(self):
self._thread = None
self._running = False
self._queues = []
self._lock = threading.Lock()
def register_queue(self, q):
with self._lock:
if q not in self._queues:
self._queues.append(q)
def unregister_queue(self, q):
with self._lock:
if q in self._queues:
self._queues.remove(q)
def start(self):
if self._running:
return
self._running = True
self._thread = threading.Thread(target=self._loop, name="analysis-event-bridge", daemon=True)
self._thread.start()
logger.info("AnalysisEventBridge 已启动")
def _loop(self):
while self._running:
handled = False
with self._lock:
queues = list(self._queues)
for q in queues:
try:
while True:
msg = q.get_nowait()
self._handle(msg)
handled = True
except queue.Empty:
continue
if not handled:
threading.Event().wait(0.05)
def _handle(self, msg):
if not msg or len(msg) < 2:
return
kind, payload = msg[0], msg[1]
try:
if kind == "event":
self._on_event(payload)
elif kind == "touch":
self._on_touch(payload)
except Exception as e:
logger.exception("事件桥处理失败: %s", e)
def _on_event(self, event):
from app.services.alarm_service import write_alarm, ALARM_EVENT_TYPES
etype = event.get("type", "")
if etype in ALARM_EVENT_TYPES:
write_alarm(event)
def _on_touch(self, payload):
# 已停用:不再写追踪快照
pass
def get_event_bridge():
global _BRIDGE
with _BRIDGE_LOCK:
if _BRIDGE is None:
_BRIDGE = AnalysisEventBridge()
_BRIDGE.start()
return _BRIDGE