88 lines
2.7 KiB
TypeScript
88 lines
2.7 KiB
TypeScript
import "server-only";
|
|
|
|
import { normalizeCanvasImageTaskQueueConfig } from "./image-task-config";
|
|
|
|
const stateKey = "__unrestricted_canvas_image_models__";
|
|
type ModelState = { running: Set<string>; durations: number[] };
|
|
function getModels() {
|
|
const globalState = globalThis as typeof globalThis & {
|
|
[stateKey]?: Map<string, ModelState>;
|
|
};
|
|
return (globalState[stateKey] ??= new Map());
|
|
}
|
|
function getModel(key: string) {
|
|
const models = getModels();
|
|
const normalized = normalizeCanvasImageModelKey(key);
|
|
let state = models.get(normalized);
|
|
if (!state) {
|
|
state = { running: new Set(), durations: [] };
|
|
models.set(normalized, state);
|
|
}
|
|
return state;
|
|
}
|
|
export function normalizeCanvasImageModelKey(value: unknown) {
|
|
return typeof value === "string" && value.trim() ? value.trim() : "__default__";
|
|
}
|
|
export async function getCanvasImageTaskQueueConfig() {
|
|
return normalizeCanvasImageTaskQueueConfig(undefined);
|
|
}
|
|
export async function getCanvasImageSingleModelConcurrency() {
|
|
return 0;
|
|
}
|
|
export async function getCanvasImageBatchDispatchIntervalMs() {
|
|
return 0;
|
|
}
|
|
export function getCanvasImageRunningCountForModel(modelKey: string) {
|
|
return getModels().get(normalizeCanvasImageModelKey(modelKey))?.running.size || 0;
|
|
}
|
|
export type CanvasImageModelQueueStatus = {
|
|
status: "pending" | "running" | "succeeded" | "failed";
|
|
queuePosition: number;
|
|
sameModelPendingCount: number;
|
|
sameModelRunningCount: number;
|
|
concurrencyLimit: number;
|
|
estimatedWaitMs: number;
|
|
source: "model_queue";
|
|
};
|
|
|
|
export async function getCanvasImageModelQueueStatus(params: {
|
|
modelKey: string;
|
|
}): Promise<CanvasImageModelQueueStatus> {
|
|
return {
|
|
status: "running",
|
|
queuePosition: 0,
|
|
sameModelPendingCount: 0,
|
|
sameModelRunningCount: getCanvasImageRunningCountForModel(params.modelKey),
|
|
concurrencyLimit: 0,
|
|
estimatedWaitMs: 0,
|
|
source: "model_queue",
|
|
};
|
|
}
|
|
export function recordCanvasImageModelExecutionDuration(modelKey: string, durationMs: number) {
|
|
if (!Number.isFinite(durationMs) || durationMs <= 0) return;
|
|
const state = getModel(modelKey);
|
|
state.durations.push(durationMs);
|
|
if (state.durations.length > 24) state.durations.shift();
|
|
}
|
|
|
|
// Keep execution tracking/release semantics, without model or owner admission limits.
|
|
export async function acquireCanvasImageModelSlot(params: {
|
|
modelKey: string;
|
|
ownerKey?: string;
|
|
debugLabel?: string;
|
|
debugMeta?: Record<string, unknown>;
|
|
onQueued?: (status: CanvasImageModelQueueStatus) => void | Promise<void>;
|
|
}) {
|
|
const state = getModel(params.modelKey);
|
|
const ticket = crypto.randomUUID();
|
|
state.running.add(ticket);
|
|
return {
|
|
release: async () => {
|
|
state.running.delete(ticket);
|
|
},
|
|
waitMs: 0,
|
|
maxConcurrent: 0,
|
|
batchDispatchIntervalMs: 0,
|
|
};
|
|
}
|