mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
feat: add maintenance concurrency modes
This commit is contained in:
134
runtime/concurrency.js
Normal file
134
runtime/concurrency.js
Normal file
@@ -0,0 +1,134 @@
|
||||
const MODE_ALIASES = Object.freeze({
|
||||
1: "strict",
|
||||
strict: "strict",
|
||||
safe: "strict",
|
||||
serial: "strict",
|
||||
2: "balanced",
|
||||
balance: "balanced",
|
||||
balanced: "balanced",
|
||||
normal: "balanced",
|
||||
3: "fast",
|
||||
fast: "fast",
|
||||
async: "fast",
|
||||
});
|
||||
|
||||
export const MAINTENANCE_EXECUTION_MODES = Object.freeze([
|
||||
"strict",
|
||||
"balanced",
|
||||
"fast",
|
||||
]);
|
||||
|
||||
function clampInt(value, fallback, min = 1, max = 64) {
|
||||
const parsed = Math.floor(Number(value));
|
||||
if (!Number.isFinite(parsed)) return fallback;
|
||||
return Math.max(min, Math.min(max, parsed));
|
||||
}
|
||||
|
||||
export function normalizeMaintenanceExecutionMode(value = "strict") {
|
||||
const normalized = String(value ?? "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
return MODE_ALIASES[normalized] || "strict";
|
||||
}
|
||||
|
||||
export function getMaintenanceExecutionModeLevel(value = "strict") {
|
||||
switch (normalizeMaintenanceExecutionMode(value)) {
|
||||
case "balanced":
|
||||
return 2;
|
||||
case "fast":
|
||||
return 3;
|
||||
case "strict":
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
export function isStrictMaintenanceMode(value = "strict") {
|
||||
return normalizeMaintenanceExecutionMode(value) === "strict";
|
||||
}
|
||||
|
||||
export function isFastMaintenanceMode(value = "strict") {
|
||||
return normalizeMaintenanceExecutionMode(value) === "fast";
|
||||
}
|
||||
|
||||
export function resolveConcurrencyConfig(settings = {}, modeOverride = null) {
|
||||
const mode = normalizeMaintenanceExecutionMode(
|
||||
modeOverride ?? settings?.maintenanceExecutionMode,
|
||||
);
|
||||
const strict = mode === "strict";
|
||||
return {
|
||||
mode,
|
||||
level: getMaintenanceExecutionModeLevel(mode),
|
||||
vectorQueryConcurrency: strict
|
||||
? 1
|
||||
: clampInt(settings?.parallelVectorQueryConcurrency, 3, 1, 12),
|
||||
neighborQueryConcurrency: strict
|
||||
? 1
|
||||
: clampInt(settings?.parallelNeighborQueryConcurrency, 3, 1, 12),
|
||||
llmConcurrency: strict
|
||||
? 1
|
||||
: clampInt(settings?.parallelLlmConcurrency, 2, 1, 4),
|
||||
backgroundMaintenanceMaxRetries: clampInt(
|
||||
settings?.backgroundMaintenanceMaxRetries,
|
||||
2,
|
||||
0,
|
||||
10,
|
||||
),
|
||||
backgroundMaintenanceRetryBaseMs: clampInt(
|
||||
settings?.backgroundMaintenanceRetryBaseMs,
|
||||
800,
|
||||
50,
|
||||
60000,
|
||||
),
|
||||
backgroundMaintenanceMaxQueueItems: clampInt(
|
||||
settings?.backgroundMaintenanceMaxQueueItems,
|
||||
24,
|
||||
1,
|
||||
256,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export function throwIfSignalAborted(signal) {
|
||||
if (!signal?.aborted) return;
|
||||
const reason = signal.reason;
|
||||
if (reason instanceof Error) throw reason;
|
||||
throw new DOMException(String(reason || "Operation aborted"), "AbortError");
|
||||
}
|
||||
|
||||
export async function runLimited(
|
||||
items = [],
|
||||
worker,
|
||||
{ concurrency = 1, signal = undefined, preserveOrder = true, failFast = true } = {},
|
||||
) {
|
||||
const list = Array.isArray(items) ? items : [];
|
||||
const limit = clampInt(concurrency, 1, 1, Math.max(1, list.length || 1));
|
||||
const results = new Array(list.length);
|
||||
let cursor = 0;
|
||||
|
||||
if (typeof worker !== "function" || list.length === 0) {
|
||||
return preserveOrder ? results : [];
|
||||
}
|
||||
|
||||
async function runWorker() {
|
||||
while (cursor < list.length) {
|
||||
throwIfSignalAborted(signal);
|
||||
const index = cursor;
|
||||
cursor += 1;
|
||||
try {
|
||||
results[index] = await worker(list[index], index);
|
||||
} catch (error) {
|
||||
if (error?.name === "AbortError") throw error;
|
||||
if (failFast) throw error;
|
||||
results[index] = { error };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const workers = Array.from(
|
||||
{ length: Math.min(limit, list.length) },
|
||||
() => runWorker(),
|
||||
);
|
||||
await Promise.all(workers);
|
||||
return preserveOrder ? results : results.filter((item) => item !== undefined);
|
||||
}
|
||||
@@ -193,6 +193,13 @@ export const defaultSettings = {
|
||||
consolidationAutoMinNewNodes: 2,
|
||||
enableAutoCompression: true,
|
||||
compressionEveryN: 10,
|
||||
maintenanceExecutionMode: "strict",
|
||||
parallelVectorQueryConcurrency: 3,
|
||||
parallelNeighborQueryConcurrency: 3,
|
||||
parallelLlmConcurrency: 2,
|
||||
backgroundMaintenanceMaxRetries: 2,
|
||||
backgroundMaintenanceRetryBaseMs: 800,
|
||||
backgroundMaintenanceMaxQueueItems: 24,
|
||||
|
||||
// UI 面板
|
||||
noticeDisplayMode: "normal",
|
||||
|
||||
Reference in New Issue
Block a user