Guard lookups when adding/deleting cameras at runtime (#23994)

* Guard object processor queue handlers against unknown cameras

* Skip embeddings post processing for removed cameras

* End review segments for removed cameras

* Drop queued autotracker moves for removed cameras

* Release tracked event thumbnails when skipping a removed camera

* Add locked accessors for camera states

* Read camera states through the processor accessors

* Guard output and recording paths against cameras not yet known

* Resolve camera state once in ONVIF, notification, and transcription paths
This commit is contained in:
Josh Hawkins
2026-09-12 07:30:04 -06:00
committed by Nicolas Mowen
parent d6a18e79aa
commit d78f6a7a98
16 changed files with 463 additions and 128 deletions
+2 -2
View File
@@ -597,7 +597,7 @@ async def _execute_get_live_context(
try:
frame_processor = request.app.detected_frames_processor
camera_state = frame_processor.camera_states.get(camera)
camera_state = frame_processor.get_camera_state(camera)
if camera_state is None:
return {
@@ -661,7 +661,7 @@ async def _get_live_frame_image_url(
return None
try:
frame_processor = request.app.detected_frames_processor
if camera not in frame_processor.camera_states:
if frame_processor.get_camera_state(camera) is None:
return None
frame = frame_processor.get_current_frame(camera, {})
if frame is None:
+2 -2
View File
@@ -1313,7 +1313,7 @@ async def set_sub_label(
if request.app.detected_frames_processor:
tracked_obj: TrackedObject = None
for state in request.app.detected_frames_processor.camera_states.values():
for state in request.app.detected_frames_processor.get_camera_states():
tracked_obj = state.tracked_objects.get(event_id)
if tracked_obj is not None:
@@ -1372,7 +1372,7 @@ async def set_plate(
if request.app.detected_frames_processor:
tracked_obj: TrackedObject = None
for state in request.app.detected_frames_processor.camera_states.values():
for state in request.app.detected_frames_processor.get_camera_states():
tracked_obj = state.tracked_objects.get(event_id)
if tracked_obj is not None:
+3 -3
View File
@@ -820,7 +820,7 @@ async def event_snapshot(
# see if the object is currently being tracked
try:
camera_states: list[CameraState] = (
request.app.detected_frames_processor.camera_states.values()
request.app.detected_frames_processor.get_camera_states()
)
for camera_state in camera_states:
if event_id in camera_state.tracked_objects:
@@ -898,7 +898,7 @@ async def event_thumbnail(
if thumbnail_bytes is None:
# see if the object is currently being tracked
try:
camera_states = request.app.detected_frames_processor.camera_states.values()
camera_states = request.app.detected_frames_processor.get_camera_states()
for camera_state in camera_states:
if event_id in camera_state.tracked_objects:
tracked_obj = camera_state.tracked_objects.get(event_id)
@@ -1127,7 +1127,7 @@ async def event_snapshot_clean(request: Request, event_id: str, download: bool =
# see if the object is currently being tracked
try:
camera_states = (
request.app.detected_frames_processor.camera_states.values()
request.app.detected_frames_processor.get_camera_states()
)
for camera_state in camera_states:
if event_id in camera_state.tracked_objects: