fix: attribute error in embedding maintainer ini… (#21252)

* fix: Resolve deadlock and attribute error in embedding maintainer initialization

Updates the trigger embedding calculation to call embedding methods directly instead of using ZMQ. This prevents a deadlock during initialization where the ZMQ responder is not yet polling for requests.

Also updates sync_triggers to pass the camera name and trigger name to the calculation method, fixing an AttributeError where trigger.name was accessed on a TriggerConfig object.

* mocked repro

* Revert "mocked repro"

This reverts commit dea5b5d4db.

* fix formatting

* Update embeddings.py

new line
This commit is contained in:
wozz 2025-12-13 09:12:09 -05:00 committed by GitHub
parent 308e692732
commit 6b9b3778f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -12,9 +12,6 @@ from peewee import DoesNotExist, IntegrityError
from PIL import Image from PIL import Image
from playhouse.shortcuts import model_to_dict from playhouse.shortcuts import model_to_dict
from frigate.comms.embeddings_updater import (
EmbeddingsRequestEnum,
)
from frigate.comms.inter_process import InterProcessRequestor from frigate.comms.inter_process import InterProcessRequestor
from frigate.config import FrigateConfig from frigate.config import FrigateConfig
from frigate.config.classification import SemanticSearchModelEnum from frigate.config.classification import SemanticSearchModelEnum
@ -495,7 +492,7 @@ class Embeddings:
or thumbnail_missing or thumbnail_missing
): ):
existing_trigger.embedding = self._calculate_trigger_embedding( existing_trigger.embedding = self._calculate_trigger_embedding(
trigger trigger, trigger_name, camera.name
) )
needs_embedding_update = True needs_embedding_update = True
@ -532,7 +529,9 @@ class Embeddings:
) )
# Calculate embedding for new trigger # Calculate embedding for new trigger
embedding = self._calculate_trigger_embedding(trigger) embedding = self._calculate_trigger_embedding(
trigger, trigger_name, camera.name
)
Trigger.create( Trigger.create(
camera=camera.name, camera=camera.name,
@ -588,14 +587,13 @@ class Embeddings:
f"Failed to delete thumbnail for trigger with data {event_id} in {camera}: {e}" f"Failed to delete thumbnail for trigger with data {event_id} in {camera}: {e}"
) )
def _calculate_trigger_embedding(self, trigger) -> bytes: def _calculate_trigger_embedding(
self, trigger, trigger_name: str, camera_name: str
) -> bytes:
"""Calculate embedding for a trigger based on its type and data.""" """Calculate embedding for a trigger based on its type and data."""
if trigger.type == "description": if trigger.type == "description":
logger.debug(f"Generating embedding for trigger description {trigger.name}") logger.debug(f"Generating embedding for trigger description {trigger_name}")
embedding = self.requestor.send_data( embedding = self.embed_description(None, trigger.data, upsert=False)
EmbeddingsRequestEnum.embed_description.value,
{"id": None, "description": trigger.data, "upsert": False},
)
return embedding.astype(np.float32).tobytes() return embedding.astype(np.float32).tobytes()
elif trigger.type == "thumbnail": elif trigger.type == "thumbnail":
@ -615,28 +613,21 @@ class Embeddings:
try: try:
with open( with open(
os.path.join( os.path.join(TRIGGER_DIR, camera_name, f"{trigger.data}.webp"),
TRIGGER_DIR, trigger.camera, f"{trigger.data}.webp"
),
"rb", "rb",
) as f: ) as f:
thumbnail = f.read() thumbnail = f.read()
except Exception as e: except Exception as e:
logger.error( logger.error(
f"Failed to read thumbnail for trigger {trigger.name} with ID {trigger.data}: {e}" f"Failed to read thumbnail for trigger {trigger_name} with ID {trigger.data}: {e}"
) )
return b"" return b""
logger.debug( logger.debug(
f"Generating embedding for trigger thumbnail {trigger.name} with ID {trigger.data}" f"Generating embedding for trigger thumbnail {trigger_name} with ID {trigger.data}"
) )
embedding = self.requestor.send_data( embedding = self.embed_thumbnail(
EmbeddingsRequestEnum.embed_thumbnail.value, str(trigger.data), thumbnail, upsert=False
{
"id": str(trigger.data),
"thumbnail": str(thumbnail),
"upsert": False,
},
) )
return embedding.astype(np.float32).tobytes() return embedding.astype(np.float32).tobytes()