From d223097ed7d32daa595ea4391f2e1c4d471c2dc1 Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Mon, 25 Jul 2022 04:11:04 -0400 Subject: [PATCH] Add pending TTS count (new API!) --- packages/components/src/api/ApiConfig.ts | 4 ++ .../src/api/tts/GetPendingTtsJobCount.ts | 45 +++++++++++++++++++ packages/fakeyou/src/v2/view/NewTopNavFc.tsx | 28 +++++++++++- 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 packages/components/src/api/tts/GetPendingTtsJobCount.ts diff --git a/packages/components/src/api/ApiConfig.ts b/packages/components/src/api/ApiConfig.ts index ba6b99b566..fc2703cc89 100644 --- a/packages/components/src/api/ApiConfig.ts +++ b/packages/components/src/api/ApiConfig.ts @@ -102,6 +102,10 @@ class ApiConfig { return `${this.getScheme()}://${this.getNewApiHost()}/tts/list`; } + getPendingTtsJobCount(): string { + return `${this.getScheme()}://${this.getNewApiHost()}/tts/queue_length`; + } + viewTtsModel(modelSlug: string): string { return `${this.getScheme()}://${this.getNewApiHost()}/tts/model/${modelSlug}`; } diff --git a/packages/components/src/api/tts/GetPendingTtsJobCount.ts b/packages/components/src/api/tts/GetPendingTtsJobCount.ts new file mode 100644 index 0000000000..c786adbe49 --- /dev/null +++ b/packages/components/src/api/tts/GetPendingTtsJobCount.ts @@ -0,0 +1,45 @@ +import { ApiConfig } from "../ApiConfig"; + +export interface GetPendingTtsJobCountSuccessResponse { + success: boolean, + pending_job_count: number, + cache_time: Date, +} + +export interface GetPendingTtsJobCountErrorResponse { +} + +export type GetPendingTtsJobCountResponse = GetPendingTtsJobCountSuccessResponse | GetPendingTtsJobCountErrorResponse; + +export function GetPendingTtsJobCountIsOk(response: GetPendingTtsJobCountResponse): response is GetPendingTtsJobCountSuccessResponse { + return response.hasOwnProperty('pending_job_count'); +} + +export function GetPendingTtsJobCountIsErr(response: GetPendingTtsJobCountResponse): response is GetPendingTtsJobCountErrorResponse { + return !response.hasOwnProperty('pending_job_count'); +} + +export async function GetPendingTtsJobCount() : Promise { + const endpoint = new ApiConfig().getPendingTtsJobCount(); + + return fetch(endpoint, { + method: 'GET', + credentials: 'include', + headers: { + 'Accept': 'application/json', + }, + }) + .then(res => res.json()) + .then(res => { + if (res && 'success' in res && res['success']) { + // NB: Timestamps aren't converted to Date objects on their own! + res['cache_time'] = new Date(res['cache_time']); + return res; + } else { + return { success : false }; + } + }) + .catch(e => { + return { success : false }; + }); +} diff --git a/packages/fakeyou/src/v2/view/NewTopNavFc.tsx b/packages/fakeyou/src/v2/view/NewTopNavFc.tsx index 202ff68fdd..7e21c293ba 100644 --- a/packages/fakeyou/src/v2/view/NewTopNavFc.tsx +++ b/packages/fakeyou/src/v2/view/NewTopNavFc.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper"; import { Link, useHistory } from "react-router-dom"; import { MigrationTopNavSession } from "../../migration/MigrationTopNav_Session"; @@ -23,6 +23,7 @@ import { t } from "i18next"; import { USE_REFRESH } from "../../Refresh"; import { Logout } from "@storyteller/components/src/api/session/Logout"; import { Gravatar } from "@storyteller/components/src/elements/Gravatar"; +import { GetPendingTtsJobCount, GetPendingTtsJobCountIsOk, GetPendingTtsJobCountSuccessResponse } from "@storyteller/components/src/api/tts/GetPendingTtsJobCount"; interface Props { sessionWrapper: SessionWrapper; @@ -40,6 +41,29 @@ function NewTopNavFc(props: Props) { myDataLink = `/profile/${username}`; } + // NB: The responses from the "job count" endpoint are cached in a distributed manner. + // We use the timestamp as a vector clock to know when to update our view. + const [pendingTtsJobs, setPendingTtsJobs] = useState({ + success: true, + pending_job_count: 0, + cache_time: new Date(0), // NB: Epoch + }); + + useEffect(() => { + const fetch = async () => { + const response = await GetPendingTtsJobCount(); + if (GetPendingTtsJobCountIsOk(response)) { + console.log(response); + if (response.cache_time.getTime() > pendingTtsJobs.cache_time.getTime()) { + setPendingTtsJobs(response); + } + } + }; + const interval = setInterval(async () => fetch(), 15000); + fetch(); + return () => clearInterval(interval); + }, [pendingTtsJobs]); + const [mobileHamburgerIsActive, setMobileHamburgerIsActive] = useState(false); @@ -326,7 +350,7 @@ function NewTopNavFc(props: Props) { Online Users: 1,204

*/}

- TTS Queued: 48 + TTS Queued: {pendingTtsJobs.pending_job_count}