From b19bf5065621c2d2150ca071394f9dc68e670b31 Mon Sep 17 00:00:00 2001 From: Victor Elias Date: Mon, 6 May 2024 16:51:52 -0300 Subject: [PATCH] api,www: Create `failed` state for recordings (#2162) * api: Add failed state to recordings Showing none is just misleading, let's show that only for stale streams * www: Handle new failed state on frontend --- packages/api/src/controllers/stream.ts | 5 ++--- packages/api/src/schema/api-schema.yaml | 1 + .../www/components/Admin/Table-v2/cells/duration.tsx | 11 ++++++++--- packages/www/components/Table/cells/duration.tsx | 12 +++++++++--- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/api/src/controllers/stream.ts b/packages/api/src/controllers/stream.ts index 38230c9b36..ead437706a 100644 --- a/packages/api/src/controllers/stream.ts +++ b/packages/api/src/controllers/stream.ts @@ -62,7 +62,6 @@ type MultistreamTargetRef = MultistreamOptions["targets"][number]; export const USER_SESSION_TIMEOUT = 60 * 1000; // 1 min export const ACTIVE_TIMEOUT = 90 * 1000; // 90 sec const STALE_SESSION_TIMEOUT = 3 * 60 * 60 * 1000; // 3 hours -const MAX_WAIT_STREAM_ACTIVE = 2 * 60 * 1000; // 2 min // Helper constant to be used in the PUT /pull API to make sure we delete fields // from the stream that are not specified in the PUT payload. @@ -524,7 +523,7 @@ export async function getRecordingFields( if (session.version === "v2") { const asset = await db.asset.getBySessionId(session.id); if (!asset) { - return { recordingStatus: "waiting" }; + return { recordingStatus: isStreamStale(session) ? "none" : "waiting" }; } const assetWithPlayback = await withPlaybackUrls(config, ingest, asset); const assetPhase = assetWithPlayback.status?.phase; @@ -533,7 +532,7 @@ export async function getRecordingFields( assetPhase == "ready" ? "ready" : assetPhase == "failed" - ? "none" + ? "failed" : "waiting", recordingUrl: assetWithPlayback.playbackUrl, mp4Url: assetWithPlayback.downloadUrl, diff --git a/packages/api/src/schema/api-schema.yaml b/packages/api/src/schema/api-schema.yaml index 65b74d02c6..06808ef91c 100644 --- a/packages/api/src/schema/api-schema.yaml +++ b/packages/api/src/schema/api-schema.yaml @@ -847,6 +847,7 @@ components: enum: - waiting - ready + - failed - none recordingUrl: type: string diff --git a/packages/www/components/Admin/Table-v2/cells/duration.tsx b/packages/www/components/Admin/Table-v2/cells/duration.tsx index af6497eff4..f6e2361151 100644 --- a/packages/www/components/Admin/Table-v2/cells/duration.tsx +++ b/packages/www/components/Admin/Table-v2/cells/duration.tsx @@ -1,17 +1,22 @@ /** @jsxImportSource @emotion/react */ -import { jsx } from "theme-ui"; +import { Session } from "@livepeer.studio/api"; import { formatDuration, intervalToDuration } from "date-fns"; import { CellComponentProps, TableData } from "../types"; -export type DurationCellProps = { duration: number; status?: string }; +export type DurationCellProps = { + duration: number; + status?: Session["recordingStatus"]; +}; const DurationCell = ({ cell, }: CellComponentProps) => { if (cell.value.status === "waiting") { return "In progress"; + } else if (cell.value.status === "failed") { + return "Failed"; } - if (cell.value.duration === 0) { + if (cell.value.duration === 0 || cell.value.status !== "ready") { return "n/a"; } try { diff --git a/packages/www/components/Table/cells/duration.tsx b/packages/www/components/Table/cells/duration.tsx index df34e4effb..bc81ebc5c7 100644 --- a/packages/www/components/Table/cells/duration.tsx +++ b/packages/www/components/Table/cells/duration.tsx @@ -1,9 +1,10 @@ +import { Session } from "@livepeer.studio/api"; import { formatDuration, intervalToDuration } from "date-fns"; import { CellComponentProps, TableData } from "../types"; export type DurationCellProps = { sourceSegmentsDuration: number; - status?: string; + status?: Session["recordingStatus"]; }; const DurationCell = ({ @@ -11,9 +12,14 @@ const DurationCell = ({ }: CellComponentProps) => { if (cell.value.status === "waiting") { return "In progress"; + } else if (cell.value.status === "failed") { + return "Failed"; } - if (cell.value.sourceSegmentsDuration === 0) { - return "—"; + if ( + cell.value.sourceSegmentsDuration === 0 || + cell.value.status !== "ready" + ) { + return "n/a"; } try { const durationMins = Math.round(cell.value.sourceSegmentsDuration / 60);