Rewrite events communication to use zmq instead of mp.Queue (#10627)

* Move to using zmq for events updating

* Use event updater in manual events handler

* Formatting
This commit is contained in:
Nicolas Mowen
2024-03-23 11:11:32 -05:00
committed by GitHub
parent 4159334520
commit 76a114a3cd
6 changed files with 117 additions and 47 deletions
+17 -22
View File
@@ -1,25 +1,19 @@
import datetime
import logging
import queue
import threading
from enum import Enum
from multiprocessing import Queue
from multiprocessing.synchronize import Event as MpEvent
from typing import Dict
from frigate.comms.events_updater import EventUpdateSubscriber
from frigate.config import EventsConfig, FrigateConfig
from frigate.events.types import EventStateEnum, EventTypeEnum
from frigate.models import Event
from frigate.types import CameraMetricsTypes
from frigate.util.builtin import to_relative_box
logger = logging.getLogger(__name__)
class EventTypeEnum(str, Enum):
api = "api"
tracked_object = "tracked_object"
def should_update_db(prev_event: Event, current_event: Event) -> bool:
"""If current_event has updated fields and (clip or snapshot)."""
if current_event["has_clip"] or current_event["has_snapshot"]:
@@ -58,8 +52,6 @@ class EventProcessor(threading.Thread):
def __init__(
self,
config: FrigateConfig,
camera_processes: dict[str, CameraMetricsTypes],
event_queue: Queue,
event_processed_queue: Queue,
timeline_queue: Queue,
stop_event: MpEvent,
@@ -67,13 +59,13 @@ class EventProcessor(threading.Thread):
threading.Thread.__init__(self)
self.name = "event_processor"
self.config = config
self.camera_processes = camera_processes
self.event_queue = event_queue
self.event_processed_queue = event_processed_queue
self.timeline_queue = timeline_queue
self.events_in_process: Dict[str, Event] = {}
self.stop_event = stop_event
self.event_receiver = EventUpdateSubscriber()
def run(self) -> None:
# set an end_time on events without an end_time on startup
Event.update(end_time=Event.start_time + 30).where(
@@ -81,13 +73,13 @@ class EventProcessor(threading.Thread):
).execute()
while not self.stop_event.is_set():
try:
source_type, event_type, camera, event_data = self.event_queue.get(
timeout=1
)
except queue.Empty:
update = self.event_receiver.check_for_update()
if update == None:
continue
source_type, event_type, camera, event_data = update
logger.debug(
f"Event received: {source_type} {event_type} {camera} {event_data['id']}"
)
@@ -103,7 +95,7 @@ class EventProcessor(threading.Thread):
)
)
if event_type == "start":
if event_type == EventStateEnum.start:
self.events_in_process[event_data["id"]] = event_data
continue
@@ -125,6 +117,7 @@ class EventProcessor(threading.Thread):
Event.update(end_time=datetime.datetime.now().timestamp()).where(
Event.end_time == None
).execute()
self.event_receiver.stop()
logger.info("Exiting event processor...")
def handle_object_detection(
@@ -247,12 +240,14 @@ class EventProcessor(threading.Thread):
# update the stored copy for comparison on future update messages
self.events_in_process[event_data["id"]] = event_data
if event_type == "end":
if event_type == EventStateEnum.end:
del self.events_in_process[event_data["id"]]
self.event_processed_queue.put((event_data["id"], camera))
def handle_external_detection(self, event_type: str, event_data: Event) -> None:
if event_type == "new":
def handle_external_detection(
self, event_type: EventStateEnum, event_data: Event
) -> None:
if event_type == EventStateEnum.start:
event = {
Event.id: event_data["id"],
Event.label: event_data["label"],
@@ -271,7 +266,7 @@ class EventProcessor(threading.Thread):
},
}
Event.insert(event).execute()
elif event_type == "end":
elif event_type == EventStateEnum.end:
event = {
Event.id: event_data["id"],
Event.end_time: event_data["end_time"],