feat(admin): 资源与策略 - 后台统一维护账号配额与运行时请求限制 (#37)
Fixes #35 Co-authored-by: ddCat <ddcat666@88.com>
This commit is contained in:
1 parent
78e27507c4
commit
d3dfede48f
40 files changed
+1202
-488
No files matched your search
@@ -7,12 +7,12 @@ import { buildGenerationConfig, generationTaskMetadata, resetGenerationTaskMetad
|
||||
import { unchangedModeratedPrompt } from "@/lib/generation-error";
|
||||
import { cancelGenerationTask, listGenerationTasks } from "@/services/api/task-center";
|
||||
import { useConfigStore, useEffectiveConfig } from "@/stores/use-config-store";
|
||||
import { useUserStore } from "@/stores/use-user-store";
|
||||
import type { CanvasGenerationBatch, CanvasGenerationBatchItem, CanvasGenerationBatchMode, CanvasNodeData } from "@/types/canvas";
|
||||
|
||||
import type { CanvasNodeGenerationOptions } from "./use-canvas-generation-executor";
|
||||
import type { CanvasNodeGenerationMode } from "@/components/canvas/canvas-node-prompt-panel";
|
||||
|
||||
const MAX_ACTIVE_TASKS_PER_USER = 5;
|
||||
const SCHEDULER_INTERVAL_MS = 2_000;
|
||||
const MAX_BATCH_HISTORY = 20;
|
||||
|
||||
@@ -31,6 +31,7 @@ export function useCanvasGenerationBatches({ projectId, projectLoaded, nodes, no
|
||||
const { message, modal } = App.useApp();
|
||||
const effectiveConfig = useEffectiveConfig();
|
||||
const isAiConfigReady = useConfigStore((state) => state.isAiConfigReady);
|
||||
const activeTaskLimit = useUserStore((state) => state.runtimeLimits.activeTaskLimit);
|
||||
const schedulingRef = useRef(false);
|
||||
const controllersRef = useRef(new Map<string, AbortController>());
|
||||
|
||||
@@ -139,7 +140,7 @@ export function useCanvasGenerationBatches({ projectId, projectLoaded, nodes, no
|
||||
});
|
||||
}, [projectId, setNodes]);
|
||||
|
||||
// 调度只补齐用户级 5 个活跃任务的空位,后端 3 个 worker 继续负责实际执行并发。
|
||||
// 调度只补齐后台返回的用户级活跃任务空位,最终并发仍由后端原子校验。
|
||||
const scheduleWaitingItems = useCallback(async () => {
|
||||
if (!projectLoaded || schedulingRef.current) return;
|
||||
schedulingRef.current = true;
|
||||
@@ -154,7 +155,7 @@ export function useCanvasGenerationBatches({ projectId, projectLoaded, nodes, no
|
||||
const item = currentNodes.flatMap((node) => node.metadata?.generationBatches || []).flatMap((batch) => batch.items).find((candidate) => candidate.id === itemId);
|
||||
return item ? !nodeById.get(item.nodeId)?.metadata?.taskId : false;
|
||||
}).length;
|
||||
let availableSlots = Math.max(0, MAX_ACTIVE_TASKS_PER_USER - activeTaskCount - pendingReservations);
|
||||
let availableSlots = Math.max(0, activeTaskLimit - activeTaskCount - pendingReservations);
|
||||
if (!availableSlots) return;
|
||||
|
||||
const candidates: Array<{ batch: CanvasGenerationBatch; item: CanvasGenerationBatchItem; node: CanvasNodeData }> = [];
|
||||
@@ -198,7 +199,7 @@ export function useCanvasGenerationBatches({ projectId, projectLoaded, nodes, no
|
||||
} finally {
|
||||
schedulingRef.current = false;
|
||||
}
|
||||
}, [effectiveConfig, handleGenerateNode, isAiConfigReady, nodesRef, projectId, projectLoaded, reconcileBatches, updateBatch]);
|
||||
}, [activeTaskLimit, effectiveConfig, handleGenerateNode, isAiConfigReady, nodesRef, projectId, projectLoaded, reconcileBatches, updateBatch]);
|
||||
|
||||
const retryFailedBatchItems = useCallback((sourceNodeId: string, batchId: string, itemId?: string) => {
|
||||
const batch = findBatch(nodesRef.current, sourceNodeId, batchId);
|
||||
|
||||
Reference in new issue
Block a user