This commit is contained in:
leo
2026-09-09 16:55:58 +02:00
parent 43ace65e0c
commit a59fc507c9
2 changed files with 57 additions and 7 deletions
+11 -2
View File
@@ -92,6 +92,12 @@ class LiveKitWebhookEventType(Enum):
class LiveKitEventsService:
"""Service for processing and handling LiveKit webhook events and notifications."""
# Terminal egress statuses LiveKit reports when the recording did not succeed.
UNSUCCESSFUL_EGRESS_EVENTS = {
api.EgressStatus.EGRESS_ABORTED: "aborted",
api.EgressStatus.EGRESS_FAILED: "failed",
}
def __init__(self):
"""Initialize with required services."""
@@ -220,7 +226,6 @@ class LiveKitEventsService:
data.egress_info.status == api.EgressStatus.EGRESS_ABORTED
and recording.status == models.RecordingStatusChoices.ACTIVE
):
self._log_egress_error(data, recording, "aborted")
try:
self.recording_events.handle_aborted(recording)
except RecordingEventsError:
@@ -232,7 +237,6 @@ class LiveKitEventsService:
data.egress_info.status == api.EgressStatus.EGRESS_FAILED
and recording.is_savable()
):
self._log_egress_error(data, recording, "failed")
try:
self.recording_events.handle_failed(recording)
except RecordingEventsError:
@@ -273,6 +277,11 @@ class LiveKitEventsService:
f"Recording with worker ID {data.egress_info.egress_id} does not exist"
) from err
# Log unsuccessful events
event = self.UNSUCCESSFUL_EGRESS_EVENTS.get(data.egress_info.status)
if event is not None:
self._log_egress_error(data, recording, event)
# Update room
try:
room_name = str(recording.room.id)
@@ -455,20 +455,30 @@ def test_handle_egress_ended_unsuccessful_egress_notification_fails(
@pytest.mark.parametrize(
("egress_status", "event"),
("egress_status", "recording_status", "event"),
(
(EgressStatus.EGRESS_ABORTED, "aborted"),
(EgressStatus.EGRESS_FAILED, "failed"),
(EgressStatus.EGRESS_ABORTED, "active", "aborted"),
(EgressStatus.EGRESS_FAILED, "active", "failed"),
# The synchronous stop may already have persisted the terminal status,
# and the error details exist only in the webhook payload.
(EgressStatus.EGRESS_ABORTED, "aborted", "aborted"),
(EgressStatus.EGRESS_FAILED, "failed", "failed"),
),
)
@mock.patch("core.utils.notify_participants")
@mock.patch("core.services.room_management.RoomManagement.update_metadata")
def test_handle_egress_ended_logs_livekit_error( # noqa: PLR0913
mock_update_metadata, mock_notify, egress_status, event, service, caplog
mock_update_metadata,
mock_notify,
egress_status,
recording_status,
event,
service,
caplog,
): # pylint: disable=too-many-arguments,too-many-positional-arguments
"""Should log the reason LiveKit reported an unsuccessful egress."""
recording = RecordingFactory(worker_id="worker-1", status="active")
recording = RecordingFactory(worker_id="worker-1", status=recording_status)
mock_data = mock.MagicMock()
mock_data.egress_info.egress_id = recording.worker_id
mock_data.egress_info.status = egress_status
@@ -483,6 +493,37 @@ def test_handle_egress_ended_logs_livekit_error( # noqa: PLR0913
assert "error_code=500" in caplog.text
@pytest.mark.parametrize(
"egress_status",
(EgressStatus.EGRESS_COMPLETE, EgressStatus.EGRESS_LIMIT_REACHED),
)
@mock.patch(
"core.recording.services.recording_events.notification_service."
"notify_external_services"
)
@mock.patch("core.utils.notify_participants")
@mock.patch("core.services.room_management.RoomManagement.update_metadata")
def test_handle_egress_ended_does_not_log_error_on_successful_egress( # noqa: PLR0913
mock_update_metadata,
mock_notify,
mock_notify_external_services,
egress_status,
service,
caplog,
): # pylint: disable=too-many-arguments,too-many-positional-arguments
"""Shouldn't log an egress error when LiveKit reports a successful egress."""
recording = RecordingFactory(worker_id="worker-1", status="active")
mock_data = mock.MagicMock()
mock_data.egress_info.egress_id = recording.worker_id
mock_data.egress_info.status = egress_status
with caplog.at_level(logging.ERROR):
service._handle_egress_ended(mock_data)
assert "Egress" not in caplog.text
@pytest.mark.parametrize(
"egress_status",
[