diff --git a/packages/components/src/api/ApiConfig.ts b/packages/components/src/api/ApiConfig.ts index 27a566e3a6..9aec49502c 100644 --- a/packages/components/src/api/ApiConfig.ts +++ b/packages/components/src/api/ApiConfig.ts @@ -326,6 +326,10 @@ class ApiConfig { return `${this.getScheme()}://${this.getNewApiHost()}/moderation/jobs/tts_inference_queue_stats`; } + killTtsInferenceJobs() : string { + return `${this.getScheme()}://${this.getNewApiHost()}/moderation/jobs/kill_tts_inference_jobs`; + } + getW2lInferenceStats() : string { return `${this.getScheme()}://${this.getNewApiHost()}/moderation/jobs/w2l_inference_queue_stats`; } diff --git a/packages/components/src/api/moderation/tts/KillTtsInferenceJobs.ts b/packages/components/src/api/moderation/tts/KillTtsInferenceJobs.ts new file mode 100644 index 0000000000..d72bc3f740 --- /dev/null +++ b/packages/components/src/api/moderation/tts/KillTtsInferenceJobs.ts @@ -0,0 +1,60 @@ + +import { ApiConfig } from "@storyteller/components"; + +export enum KillAction { + AllPending = 'all_pending', + AllPendingAndFailed = 'all_pending_and_failed', + ZeroPriorityPending = 'zero_priority_pending', +} + +export interface KillTtsInferenceJobsRequest { + kill_action: KillAction, +} + +export interface KillTtsInferenceJobsSuccessResponse { + success: boolean, +} + +export interface KillTtsInferenceJobsErrorResponse { + success: boolean, +} + +type KillTtsInferenceJobsResponse = KillTtsInferenceJobsSuccessResponse | KillTtsInferenceJobsErrorResponse; + +export function KillTtsInferenceJobsIsSuccess(response: KillTtsInferenceJobsResponse): response is KillTtsInferenceJobsSuccessResponse { + return response?.success === true; +} + +export function KillTtsInferenceJobsIsError(response: KillTtsInferenceJobsResponse): response is KillTtsInferenceJobsErrorResponse { + return response?.success === false; +} + +export async function KillTtsInferenceJobs(request: KillTtsInferenceJobsRequest) : Promise +{ + const endpoint = new ApiConfig().killTtsInferenceJobs(); + + return await fetch(endpoint, { + method: 'POST', + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + credentials: 'include', + body: JSON.stringify(request), + }) + .then(res => res.json()) + .then(res => { + if (!res) { + return { success : false }; + } + + if (res && 'success' in res) { + return res; + } else { + return { success : false }; + } + }) + .catch(e => { + return { success : false }; + }); +} diff --git a/packages/fakeyou/src/v2/api/moderation/GetTtsInferenceStats.ts b/packages/fakeyou/src/v2/api/moderation/GetTtsInferenceStats.ts index 80f1f19c35..ecf46927c6 100644 --- a/packages/fakeyou/src/v2/api/moderation/GetTtsInferenceStats.ts +++ b/packages/fakeyou/src/v2/api/moderation/GetTtsInferenceStats.ts @@ -2,8 +2,11 @@ import { ApiConfig } from "@storyteller/components"; export interface TtsInferenceStats { success: boolean, - pending_count: number, seconds_since_first: number, + pending_count: number, + pending_priority_nonzero_count: number, + pending_priority_gt_one_count: number, + attempt_failed_count: number, } export enum TtsInferenceStatsError { diff --git a/packages/fakeyou/src/v2/view/moderation/moderation_job_stats/ModerationJobStatsFc.tsx b/packages/fakeyou/src/v2/view/moderation/moderation_job_stats/ModerationJobStatsFc.tsx index 600e60ec55..d2f63dc8e1 100644 --- a/packages/fakeyou/src/v2/view/moderation/moderation_job_stats/ModerationJobStatsFc.tsx +++ b/packages/fakeyou/src/v2/view/moderation/moderation_job_stats/ModerationJobStatsFc.tsx @@ -4,22 +4,33 @@ import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig'; import { BackLink } from '../../_common/BackLink'; import { GetTtsInferenceStats, GetTtsInferenceStatsIsOk } from '../../../api/moderation/GetTtsInferenceStats'; import { GetW2lInferenceStats, GetW2lInferenceStatsIsOk } from '../../../api/moderation/GetW2lInferenceStats'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faBomb, faRedo } from '@fortawesome/free-solid-svg-icons'; interface Props { sessionWrapper: SessionWrapper, } function ModerationJobStatsFc(props: Props) { - const [ttsPendingJobCount, setTtsPendingJobCount] = useState(-1); + // NB: We have more TTS stats than W2L stats now. const [ttsSecondsSinceFirst, setTtsSecondsSinceFirst] = useState(-1); + const [ttsPendingJobCount, setTtsPendingJobCount] = useState(-1); + const [ttsPendingPriorityNonzeroJobCount, setTtsPendingPriorityNonzeroJobCount] = useState(-1); + const [ttsPendingPriorityGtOneJobCount, setTtsPendingPriorityGtOneJobCount] = useState(-1); + const [ttsAttemptFailedJobCount, setTtsAttemptFailedJobCount] = useState(-1); + + const [w2lPendingJobCount, setW2lPendingJobCount] = useState(-1); const [w2lSecondsSinceFirst, setW2lSecondsSinceFirst] = useState(-1); const getTtsStats = useCallback(async () => { const response = await GetTtsInferenceStats(); if (GetTtsInferenceStatsIsOk(response)) { - setTtsPendingJobCount(response.pending_count); setTtsSecondsSinceFirst(response.seconds_since_first); + setTtsPendingJobCount(response.pending_count); + setTtsPendingPriorityNonzeroJobCount(response.pending_priority_nonzero_count); + setTtsPendingPriorityGtOneJobCount(response.pending_priority_gt_one_count); + setTtsAttemptFailedJobCount(response.attempt_failed_count); } }, []); @@ -40,6 +51,16 @@ function ModerationJobStatsFc(props: Props) { reloadStats(); }, [reloadStats]); + const killPending = async () => { + reloadStats(); + } + const killPendingAndFailed = async () => { + reloadStats(); + } + + const killZeroPriorityPending = async () => { + reloadStats(); + } if (ttsPendingJobCount === -1 && w2lPendingJobCount === -1) { return
@@ -61,37 +82,132 @@ function ModerationJobStatsFc(props: Props) {

- +

TTS Stats

+ +
- - - + + + + +
Pending jobsWait timeMisc Stats
- TTS Inference + TTS wait time + {ttsWait}
+ + + + + + + + + + - - - + + + + + + + + + + + + +
Failed Jobs by Type
+ All Jobs {ttsPendingJobCount} pending {ttsWait}
- W2L Inference + Priority > 0 {w2lPendingJobCount} pending {w2lWait}{ttsPendingJobCount} pending
+ Priority > 1 + {ttsPendingJobCount} pending
+ Retryably failed + {ttsPendingJobCount} pending
Wait timesummary statistics, job counts, etc.

+ +

W2L Stats

+ + + + + + + + + + + + + +
Misc Stats
+ W2L wait time + {w2lWait}
+ + + + + + + + + + + + + + +
Failed Jobs by Type
+ All Jobs + {w2lPendingJobCount} pending
+ +
+ +

Reload Job Stats

+ + >Reload  + +
+
+ +

Kill Stuck Jobs (Danger Zone)

+

(Please don't do this.)

+ + + +
+ + + +
+ +
) }