From f19bafdb0c43d20b0fa7963f9326f15d8364cd20 Mon Sep 17 00:00:00 2001 From: wil Date: Tue, 9 Apr 2024 21:28:13 -0400 Subject: [PATCH] inference panel and inference manager are doing great --- app/hooks/index.tsx | 1 + app/hooks/useInferenceJobManager/index.tsx | 1 + .../useInferenceJobManager.tsx | 116 ++++++++++++++++++ .../DialogueInference/DialogueInference.tsx | 29 +---- app/pages/PageEnigma/PageEnigma.tsx | 5 + app/pages/PageEnigma/Queue/Queue.ts | 16 ++- app/pages/PageEnigma/Queue/QueueNames.ts | 1 - .../comps/DialogueTTS/DialogueTTS.tsx | 17 ++- .../AudioTabComponent/AudioTabComponent.tsx | 42 +++---- app/pages/PageEnigma/models/inferenceJobs.tsx | 3 +- app/pages/PageEnigma/store/inferenceJobs.ts | 23 ++-- app/root.tsx | 6 + 12 files changed, 187 insertions(+), 73 deletions(-) create mode 100644 app/hooks/index.tsx create mode 100644 app/hooks/useInferenceJobManager/index.tsx create mode 100644 app/hooks/useInferenceJobManager/useInferenceJobManager.tsx diff --git a/app/hooks/index.tsx b/app/hooks/index.tsx new file mode 100644 index 0000000000..5cc28acb16 --- /dev/null +++ b/app/hooks/index.tsx @@ -0,0 +1 @@ +export { useInferenceJobManager } from "./useInferenceJobManager"; \ No newline at end of file diff --git a/app/hooks/useInferenceJobManager/index.tsx b/app/hooks/useInferenceJobManager/index.tsx new file mode 100644 index 0000000000..e048c44906 --- /dev/null +++ b/app/hooks/useInferenceJobManager/index.tsx @@ -0,0 +1 @@ +export { useInferenceJobManager } from './useInferenceJobManager'; diff --git a/app/hooks/useInferenceJobManager/useInferenceJobManager.tsx b/app/hooks/useInferenceJobManager/useInferenceJobManager.tsx new file mode 100644 index 0000000000..cc4e91928b --- /dev/null +++ b/app/hooks/useInferenceJobManager/useInferenceJobManager.tsx @@ -0,0 +1,116 @@ +import { useEffect, useCallback } from "react"; +import { useSignals } from "@preact/signals-react/runtime"; +import { inferenceJobs, updateInferenceJob } from '~/pages/PageEnigma/store/inferenceJobs'; + +export enum JobState { + UNKNOWN = "unknown", // Only on frontend. + PENDING = "pending", + STARTED = "started", + COMPLETE_SUCCESS = "complete_success", + COMPLETE_FAILURE = "complete_failure", + ATTEMPT_FAILED = "attempt_failed", + DEAD = "dead", + CANCELED_BY_USER = "canceled_by_user", +} +export interface RequestDetails { + inference_category: string, + maybe_model_type?: string, + maybe_model_token?: string, + maybe_model_title?: string, + maybe_raw_inference_text?: string, +} + +export interface StatusDetails { + status: string, + maybe_extra_status_description?: string, + maybe_failure_category?: string, + attempt_count: number, +} + +export interface ResultDetails { + entity_type: string, + entity_token: string, + maybe_public_bucket_media_path?: string, +} + +export interface JobStatus { + job_token: string, + request: RequestDetails, + status: StatusDetails, + maybe_result?: ResultDetails, + created_at: Date, + updated_at: Date, +} + +export interface GetJobStatusResponse { + success: boolean; + state: JobStatus +} +type ErrorResponse = { + success: boolean; + error_reason: string; +} +export async function GetInferenceJobStatus(jobToken:string) : Promise { + + const endpoint = `https://api.fakeyou.com/v1/model_inference/job_status/${jobToken}`; + + return await fetch(endpoint, { + method: 'GET', + headers: { + 'Accept': 'application/json', + }, + credentials: 'include', + }) + .then(res => res.json()) + .then(res => { + const response : GetJobStatusResponse = res; + return response; + }) + .catch(e => { + return null; + }); +} + +function shouldKeepPolling(currStatus:string){ + if(currStatus === JobState.PENDING + || currStatus === JobState.STARTED + ) return true; + return false +} + +export const useInferenceJobManager = () => { + useSignals(); + + const pollInferenceJobs = useCallback(()=>{ + if(inferenceJobs.value.length > 0 ){ + inferenceJobs.value.forEach(job=>{ + if(shouldKeepPolling(job.job_status)){ + GetInferenceJobStatus(job.job_id).then((res:GetJobStatusResponse|null)=>{ + if(res!==null){ + if(res.state.status.status !== job.job_status){ + console.log(`${res.state.job_token} has new state: ${res.state.status.status}`) + if(res.state.status.status === JobState.COMPLETE_SUCCESS){ + console.log(res.state); + } + updateInferenceJob({ + ...job, + job_status: res.state.status.status + }) + } + } + }); + } + }); + } + }, []); + + useEffect(()=>{ + console.log('useInferenceJobManager Mounted'); + const intervalTimer = setInterval(pollInferenceJobs,2000); + return()=>{ + console.log('useInferenceJobManager Dismounted'); + clearInterval(intervalTimer); + } + },[]); +}; + diff --git a/app/modules/DialogueInference/DialogueInference.tsx b/app/modules/DialogueInference/DialogueInference.tsx index b534f624e7..0b27257eb8 100644 --- a/app/modules/DialogueInference/DialogueInference.tsx +++ b/app/modules/DialogueInference/DialogueInference.tsx @@ -1,33 +1,12 @@ -import { useEffect, useState } from "react"; - import { useSignals } from "@preact/signals-react/runtime"; import { faClipboard, faClipboardList } from "@fortawesome/pro-solid-svg-icons"; import { inferenceJobs } from "~/pages/PageEnigma/store/inferenceJobs"; import { ButtonDialogue } from "../ButtonDialogue"; import { H4, P } from "~/components"; -import Queue from "~/pages/PageEnigma/Queue/Queue"; -import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames"; -import { InferenceJob } from "~/pages/PageEnigma/models"; export const DialogueInference = () =>{ useSignals(); - const [inferenceJobsState, setInferenceJobsState] = useState(inferenceJobs.value); - - const handleInferenceJobs = (data:any)=>{ - console.log('Dialogue Inference > useEffect >>>'); - console.log(data); - console.log(inferenceJobs.value); - setInferenceJobsState([...inferenceJobs.value]); - console.log('<<< Dialogue Inference'); - } - useEffect(()=>{ - Queue.subscribe( - QueueNames.TO_INFERENCE, - handleInferenceJobs, - ); - - },[]); const buttonIcon = inferenceJobs.value.length > 0 ? faClipboardList : faClipboard; @@ -41,15 +20,15 @@ export const DialogueInference = () =>{ }} >

List :-

- {inferenceJobsState.length > 0 && + {inferenceJobs.value.length > 0 &&
    - {inferenceJobsState.map(job=> -
  • {job.jobt_type} : {job.job_id}
  • + {inferenceJobs.value.map(job=> +
  • {job.job_type}: {job.job_status} : {job.job_id}
  • )}
} { - inferenceJobsState.length === 0 && + inferenceJobs.value.length === 0 &&

no inference jobs

} diff --git a/app/pages/PageEnigma/PageEnigma.tsx b/app/pages/PageEnigma/PageEnigma.tsx index 67f3530d30..168d595ce2 100644 --- a/app/pages/PageEnigma/PageEnigma.tsx +++ b/app/pages/PageEnigma/PageEnigma.tsx @@ -3,12 +3,16 @@ import { TrackProvider } from "~/pages/PageEnigma/contexts/TrackContext/TrackPro import { AppUIProvider } from "~/pages/PageEnigma/contexts/AppUiContext"; import { EngineProvider } from "~/pages/PageEnigma/contexts/EngineProvider"; import { DragComponent } from "~/pages/PageEnigma/comps/DragComponent/DragComponent"; + +import { useInferenceJobManager } from "~/hooks"; + // import { toast, ToastBar, Toaster } from "react-hot-toast"; // import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; // import { // faTriangleExclamation, // faXmark, // } from "@fortawesome/pro-solid-svg-icons"; + import { useEffect } from "react"; import { useSignals } from "@preact/signals-react/runtime"; import { @@ -20,6 +24,7 @@ import { export const PageEnigma = () => { useSignals(); + useInferenceJobManager(); useEffect(() => { function setPage() { // TODO address this issue with zooming diff --git a/app/pages/PageEnigma/Queue/Queue.ts b/app/pages/PageEnigma/Queue/Queue.ts index 31c5b31d63..5b989dbdff 100644 --- a/app/pages/PageEnigma/Queue/Queue.ts +++ b/app/pages/PageEnigma/Queue/Queue.ts @@ -1,19 +1,20 @@ -import { toInferenceActions } from './toInferenceActions'; - import { fromEngineActions } from "~/pages/PageEnigma/Queue/fromEngineActions"; import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions"; import { QueueClip, QueueKeyframe, - InferenceJob, UpdateTime, } from "~/pages/PageEnigma/models"; import { toTimelineActions } from "./toTimelineActions"; -type UnionedActionTypes = fromEngineActions | toEngineActions | toTimelineActions | toInferenceActions; -type UnionedDataTypes = QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem | InferenceJob; +type UnionedActionTypes = fromEngineActions | toEngineActions | toTimelineActions; +type UnionedDataTypes = QueueClip | UpdateTime | QueueKeyframe | ClipUI[] | MediaItem; +export type QueueSubscribeType = { + action: UnionedActionTypes; + data: UnionedDataTypes; +} import { ClipUI } from "../datastructures/clips/clip_ui"; import { MediaItem } from "~/pages/PageEnigma/models"; class Queue { @@ -54,10 +55,7 @@ class Queue { public subscribe( queueName: string, - onMessage: (entry: { - action: UnionedActionTypes; - data: UnionedDataTypes; - }) => void, + onMessage: (entry: QueueSubscribeType) => void, ) { this._subscribers[queueName] = onMessage; while (this._queue[queueName]?.length) { diff --git a/app/pages/PageEnigma/Queue/QueueNames.ts b/app/pages/PageEnigma/Queue/QueueNames.ts index b558ef002f..813a726847 100644 --- a/app/pages/PageEnigma/Queue/QueueNames.ts +++ b/app/pages/PageEnigma/Queue/QueueNames.ts @@ -2,5 +2,4 @@ export enum QueueNames { FROM_ENGINE = "FROM_ENGINE", TO_ENGINE = "TO_ENGINE", TO_TIMELINE = "TO_TIMELINE", - TO_INFERENCE = "TO_INFERENCE", } diff --git a/app/pages/PageEnigma/comps/DialogueTTS/DialogueTTS.tsx b/app/pages/PageEnigma/comps/DialogueTTS/DialogueTTS.tsx index c32ef6d61a..78eb11eca9 100644 --- a/app/pages/PageEnigma/comps/DialogueTTS/DialogueTTS.tsx +++ b/app/pages/PageEnigma/comps/DialogueTTS/DialogueTTS.tsx @@ -64,7 +64,8 @@ export const DialogueTTS = ()=>{ addInferenceJob({ version:1, job_id: ttsState.inferenceToken, - jobt_type: ttsState.inferenceJobType, + job_type: ttsState.inferenceJobType, + job_status: "pending", }) } },[ttsState.hasEnqueued]); @@ -157,7 +158,7 @@ export const DialogueTTS = ()=>{ onChange={handleTextInput} />
-
+
{!ttsState.hasAudio && !ttsState.hasEnqueued &&
-
+
+ { ttsState.hasEnqueued && + + } + @@ -67,19 +78,6 @@ export const AudioTabComponent = () => { items={audioItems.value} assetFilter={audioFilter.value} /> - -

inference jobs

- {inferenceJobs.value.length > 0 && -
    - {inferenceJobs.value.map(job=> -
  • {job.jobt_type} : {job.job_id}
  • - )} -
- } - { - inferenceJobs.value.length === 0 && -

no inference jobs

- }
); diff --git a/app/pages/PageEnigma/models/inferenceJobs.tsx b/app/pages/PageEnigma/models/inferenceJobs.tsx index fb195ac456..12039bd041 100644 --- a/app/pages/PageEnigma/models/inferenceJobs.tsx +++ b/app/pages/PageEnigma/models/inferenceJobs.tsx @@ -1,5 +1,6 @@ export interface InferenceJob { version: number; job_id: string; - jobt_type: string; + job_type: string; + job_status: string; } diff --git a/app/pages/PageEnigma/store/inferenceJobs.ts b/app/pages/PageEnigma/store/inferenceJobs.ts index 092168dcd0..1d3dd62ca9 100644 --- a/app/pages/PageEnigma/store/inferenceJobs.ts +++ b/app/pages/PageEnigma/store/inferenceJobs.ts @@ -1,11 +1,5 @@ import { signal } from "@preact/signals-core"; -import Queue from "~/pages/PageEnigma/Queue/Queue"; -import { QueueNames } from "../Queue/QueueNames"; -import { toInferenceActions } from "../Queue/toInferenceActions"; -// import * as uuid from "uuid"; -// import { signal } from "@preact/signals-core"; - import { InferenceJob } from "../models"; export const inferenceJobs = signal([]); @@ -13,12 +7,17 @@ export const inferenceJobs = signal([]); export function addInferenceJob( inferenceJob: InferenceJob){ const existingInferenceJobs = inferenceJobs.value; - existingInferenceJobs.push(inferenceJob); + inferenceJobs.value = [...existingInferenceJobs]; +} - Queue.publish({ - queueName: QueueNames.TO_INFERENCE, - action: toInferenceActions.ADD_TTS_JOB, - data: inferenceJob, - }); +export function updateInferenceJob( + inferenceJob: InferenceJob){ + const existingInferenceJobs = inferenceJobs.value; + existingInferenceJobs.forEach(job=>{ + if(job.job_id === inferenceJob.job_id){ + job.job_status = inferenceJob.job_status + } + }) + inferenceJobs.value = [...existingInferenceJobs]; } \ No newline at end of file diff --git a/app/root.tsx b/app/root.tsx index 1017fbe028..03e56f23ed 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -18,6 +18,12 @@ import { LoadingDotsBricks } from "~/components"; import { TopBar } from "./modules/TopBar"; import { TopBarInnerContext } from "~/contexts/TopBarInner"; import { AuthenticationProvider, UserInfo } from "./contexts/Authentication"; +// The following import prevents a Font Awesome icon server-side rendering bug, +// where the icons flash from a very large icon down to a properly sized one: +import '@fortawesome/fontawesome-svg-core/styles.css'; +// Prevent fontawesome from adding its CSS since we did it manually above: +import { config } from '@fortawesome/fontawesome-svg-core'; +config.autoAddCss = false; /* eslint-disable import/first */ export const links: LinksFunction = () => [ {