This commit is contained in:
leo
2026-07-20 15:50:42 +02:00
parent ab707d866f
commit 2f59d9281c
4 changed files with 47 additions and 6 deletions
+1
View File
@@ -33,6 +33,7 @@ and this project adheres to
- 🩹(backend) identify externally provisioned users to PostHog
- 🐛(backend) fix info panel crash for unregistered rooms
- ♿️(frontend) focus side panel container on open #1452
- 🩹(backend) handle failed and aborted egresses
## [1.23.0] - 2026-07-08
+8 -1
View File
@@ -57,6 +57,7 @@ class RecordingStatusChoices(models.TextChoices):
STOPPED = "stopped", _("Stopped")
SAVED = "saved", _("Saved")
ABORTED = "aborted", _("Aborted")
FAILED = "failed", _("Failed")
FAILED_TO_START = "failed_to_start", _("Failed to Start")
FAILED_TO_STOP = "failed_to_stop", _("Failed to Stop")
NOTIFICATION_SUCCEEDED = "notification_succeeded", _("Notification succeeded")
@@ -80,6 +81,7 @@ class RecordingStatusChoices(models.TextChoices):
cls.ABORTED,
cls.EXTERNAL_PROCESS_SUCCESSFUL,
cls.EXTERNAL_PROCESS_FAILED,
cls.FAILED,
cls.FAILED_TO_START,
cls.FAILED_TO_STOP,
}
@@ -87,7 +89,12 @@ class RecordingStatusChoices(models.TextChoices):
@classmethod
def is_unsuccessful(cls, status):
"""Determine if the recording status represents an unsuccessful state."""
return status in {cls.ABORTED, cls.FAILED_TO_START, cls.FAILED_TO_STOP}
return status in {
cls.ABORTED,
cls.FAILED,
cls.FAILED_TO_START,
cls.FAILED_TO_STOP,
}
class RecordingModeChoices(models.TextChoices):
@@ -26,14 +26,16 @@ class RecordingEventsService:
@staticmethod
def handle_update(recording: Recording, egress_status):
"""Handle egress status updates and sync recording state to room metadata."""
"""Handle egress update and sync recording state to room metadata.
Egress updates are sent for statuses EGRESS_ACTIVE and EGRESS_ENDING.
"""
room_name = str(recording.room.id)
status_mapping = {
api.EgressStatus.EGRESS_ACTIVE: "started",
api.EgressStatus.EGRESS_ENDING: "saving",
api.EgressStatus.EGRESS_ABORTED: "aborted",
}
recording_status = status_mapping.get(egress_status)
@@ -59,6 +61,13 @@ class RecordingEventsService:
notification_type = notification_mapping.get(recording.mode)
if not notification_type:
logger.warning(
"Could not find notification type for: "
"room=%s, recording_id=%s, mode=%s",
recording.room.id,
recording.id,
recording.mode,
)
return
try:
@@ -79,6 +88,18 @@ class RecordingEventsService:
f"recording limit reached (recording_id={recording.id})"
) from e
@staticmethod
def handle_failed(recording: Recording):
"""Set recording status to failed, matching egress status."""
recording.status = models.RecordingStatusChoices.FAILED
recording.save()
@staticmethod
def handle_aborted(recording: Recording):
"""Set recording status to aborted, matching egress status."""
recording.status = models.RecordingStatusChoices.ABORTED
recording.save()
@staticmethod
def handle_complete(recording: Recording):
"""Notify external services and save recording."""
+15 -3
View File
@@ -200,7 +200,21 @@ class LiveKitEventsService:
f"Failed to process limit reached event for recording {recording}"
) from e
# Fallback for completion when no MinIO/S3 webhooks are configured
if (
data.egress_info.status == api.EgressStatus.EGRESS_ABORTED
and recording.status == models.RecordingStatusChoices.ACTIVE
):
return self.recording_events.handle_aborted(recording)
if (
data.egress_info.status == api.EgressStatus.EGRESS_FAILED
and recording.status == models.RecordingStatusChoices.ACTIVE
):
return self.recording_events.handle_failed(recording)
# Fallback for completion when no MinIO/S3 webhooks are configured.
# If RECORDING_STORAGE_EVENT_ENABLE is True, completion is handled
# by ``on_storage_event_received``.
if (
not settings.RECORDING_STORAGE_EVENT_ENABLE
) and data.egress_info.status in [
@@ -216,8 +230,6 @@ class LiveKitEventsService:
recording.id,
)
# Silently ignoring EGRESS_ABORTED, EGRESS_FAILED
def _handle_room_started(self, data):
"""Handle 'room_started' event."""