fix: harden generation task recovery
This commit is contained in:
@@ -6,6 +6,7 @@ import type {
|
||||
CanvasVideoGenerationState,
|
||||
CanvasVideoNode,
|
||||
} from "./canvasTypes";
|
||||
import { aiGenerationClient } from "../../api/aiGenerationClient";
|
||||
import { createCanvasAssetRefFromGeneratedResult, persistCanvasGeneratedResultAsset } from "./canvasAssetPersistence";
|
||||
import { waitForImageTaskResult, waitForVideoTaskResult } from "./canvasUtils";
|
||||
|
||||
@@ -41,6 +42,13 @@ export function removeCanvasGenKeepalive(taskId: string): void {
|
||||
saveCanvasGenKeepalive(loadCanvasGenKeepalive().filter((e) => e.taskId !== taskId));
|
||||
}
|
||||
|
||||
export function cancelCanvasGenKeepaliveOnUnload(): void {
|
||||
const entries = loadCanvasGenKeepalive();
|
||||
if (!entries.length) return;
|
||||
entries.forEach((entry) => aiGenerationClient.cancelTaskOnUnload(entry.taskId));
|
||||
saveCanvasGenKeepalive([]);
|
||||
}
|
||||
|
||||
export interface UseCanvasGenerationParams {
|
||||
setImageNodes: Dispatch<SetStateAction<CanvasImageNode[]>>;
|
||||
setVideoNodes: Dispatch<SetStateAction<CanvasVideoNode[]>>;
|
||||
@@ -55,6 +63,7 @@ export function useCanvasGeneration(params: UseCanvasGenerationParams) {
|
||||
const [generationToast, setGenerationToast] = useState<string | null>(null);
|
||||
|
||||
const imageGenerationInFlightRef = useRef(new Set<string>());
|
||||
const videoGenerationInFlightRef = useRef(new Set<string>());
|
||||
const textGenerationInFlightRef = useRef(new Set<string>());
|
||||
const textGenerationAbortControllersRef = useRef(new Map<string, AbortController>());
|
||||
const canvasGenKeepaliveRestoredRef = useRef(false);
|
||||
@@ -125,7 +134,7 @@ export function useCanvasGeneration(params: UseCanvasGenerationParams) {
|
||||
imageGenerationInFlightRef.current.delete(entry.nodeId);
|
||||
});
|
||||
} else if (entry.nodeKind === "video") {
|
||||
imageGenerationInFlightRef.current.add(entry.nodeId);
|
||||
videoGenerationInFlightRef.current.add(entry.nodeId);
|
||||
setVideoGenerationStatus(entry.nodeId, { status: "running", message: "正在恢复视频生成", progress: 20 });
|
||||
void waitForVideoTaskResult(entry.taskId, (status) => {
|
||||
const progress = Math.max(18, Math.min(status.status === "completed" ? 100 : 96, Math.trunc(status.progress || 0)));
|
||||
@@ -154,7 +163,7 @@ export function useCanvasGeneration(params: UseCanvasGenerationParams) {
|
||||
removeCanvasGenKeepalive(entry.taskId);
|
||||
setVideoGenerationStatus(entry.nodeId, { status: "error", message: "视频生成失败" });
|
||||
}).finally(() => {
|
||||
imageGenerationInFlightRef.current.delete(entry.nodeId);
|
||||
videoGenerationInFlightRef.current.delete(entry.nodeId);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -165,11 +174,36 @@ export function useCanvasGeneration(params: UseCanvasGenerationParams) {
|
||||
textGenerationAbortControllersRef.current.clear();
|
||||
textGenerationInFlightRef.current.clear();
|
||||
imageGenerationInFlightRef.current.clear();
|
||||
videoGenerationInFlightRef.current.clear();
|
||||
setTextGenerationState({});
|
||||
setImageGenerationState({});
|
||||
setVideoGenerationState({});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const handlePageHide = () => {
|
||||
cancelCanvasGenKeepaliveOnUnload();
|
||||
textGenerationAbortControllersRef.current.forEach((controller) => controller.abort());
|
||||
textGenerationAbortControllersRef.current.clear();
|
||||
textGenerationInFlightRef.current.clear();
|
||||
imageGenerationInFlightRef.current.clear();
|
||||
videoGenerationInFlightRef.current.clear();
|
||||
setTextGenerationState({});
|
||||
setImageGenerationState({});
|
||||
setVideoGenerationState({});
|
||||
};
|
||||
const handleOnline = () => {
|
||||
aiGenerationClient.flushPendingTaskCancellations();
|
||||
};
|
||||
window.addEventListener("pagehide", handlePageHide);
|
||||
window.addEventListener("online", handleOnline);
|
||||
aiGenerationClient.flushPendingTaskCancellations();
|
||||
return () => {
|
||||
window.removeEventListener("pagehide", handlePageHide);
|
||||
window.removeEventListener("online", handleOnline);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return {
|
||||
textGenerationState,
|
||||
imageGenerationState,
|
||||
@@ -177,6 +211,7 @@ export function useCanvasGeneration(params: UseCanvasGenerationParams) {
|
||||
generationToast,
|
||||
setGenerationToast,
|
||||
imageGenerationInFlightRef,
|
||||
videoGenerationInFlightRef,
|
||||
textGenerationInFlightRef,
|
||||
textGenerationAbortControllersRef,
|
||||
canvasGenKeepaliveRestoredRef,
|
||||
|
||||
Reference in New Issue
Block a user