131 lines
3.6 KiB
TypeScript
131 lines
3.6 KiB
TypeScript
export const CANVAS_IMAGE_TASK_QUEUE_CONFIG_KEY = "canvas_image_task_queue_config";
|
|
|
|
export const MIN_CANVAS_IMAGE_TASK_CONCURRENCY = 1;
|
|
export const DEFAULT_CANVAS_IMAGE_TASK_CONCURRENCY = 3;
|
|
export const MAX_CANVAS_IMAGE_TASK_CONCURRENCY = 100;
|
|
export const MIN_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS = 0;
|
|
export const DEFAULT_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS = 0;
|
|
export const MAX_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS = 60 * 1000;
|
|
|
|
export interface CanvasImageTaskQueueConfig {
|
|
concurrency: number;
|
|
batchDispatchIntervalMs: number;
|
|
}
|
|
|
|
function clampConcurrency(value: number) {
|
|
return Math.min(
|
|
MAX_CANVAS_IMAGE_TASK_CONCURRENCY,
|
|
Math.max(MIN_CANVAS_IMAGE_TASK_CONCURRENCY, Math.floor(value))
|
|
);
|
|
}
|
|
|
|
function clampBatchDispatchIntervalMs(value: number) {
|
|
return Math.min(
|
|
MAX_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS,
|
|
Math.max(MIN_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS, Math.floor(value))
|
|
);
|
|
}
|
|
|
|
function parseConcurrencyCandidate(value: unknown): number | null {
|
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
return clampConcurrency(value);
|
|
}
|
|
|
|
if (typeof value === "string" && value.trim()) {
|
|
const parsed = Number.parseInt(value.trim(), 10);
|
|
if (Number.isFinite(parsed)) {
|
|
return clampConcurrency(parsed);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
function parseBatchDispatchIntervalCandidate(
|
|
value: unknown,
|
|
options?: { treatAsSeconds?: boolean }
|
|
): number | null {
|
|
const normalize = (candidate: number) =>
|
|
clampBatchDispatchIntervalMs(
|
|
options?.treatAsSeconds ? candidate * 1000 : candidate
|
|
);
|
|
|
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
return normalize(value);
|
|
}
|
|
|
|
if (typeof value === "string" && value.trim()) {
|
|
const parsed = Number.parseFloat(value.trim());
|
|
if (Number.isFinite(parsed)) {
|
|
return normalize(parsed);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function normalizeCanvasImageTaskQueueConfig(
|
|
value: unknown,
|
|
options?: { envConcurrency?: unknown; envBatchDispatchIntervalMs?: unknown }
|
|
): CanvasImageTaskQueueConfig {
|
|
const raw = value && typeof value === "object" && !Array.isArray(value)
|
|
? (value as Record<string, unknown>)
|
|
: {};
|
|
|
|
const concurrencyCandidates = [
|
|
raw.concurrency,
|
|
raw.maxConcurrency,
|
|
raw.maxConcurrent,
|
|
typeof value === "number" || typeof value === "string" ? value : undefined,
|
|
options?.envConcurrency,
|
|
];
|
|
|
|
let concurrency = DEFAULT_CANVAS_IMAGE_TASK_CONCURRENCY;
|
|
for (const candidate of concurrencyCandidates) {
|
|
const parsed = parseConcurrencyCandidate(candidate);
|
|
if (parsed !== null) {
|
|
concurrency = parsed;
|
|
break;
|
|
}
|
|
}
|
|
|
|
const intervalCandidates = [
|
|
raw.batchDispatchIntervalMs,
|
|
raw.dispatchIntervalMs,
|
|
raw.batchDispatchDelayMs,
|
|
raw.batchDispatchInterval,
|
|
raw.dispatchInterval,
|
|
options?.envBatchDispatchIntervalMs,
|
|
];
|
|
const intervalSecondsCandidates = [
|
|
raw.batchDispatchIntervalSeconds,
|
|
raw.dispatchIntervalSeconds,
|
|
];
|
|
|
|
let batchDispatchIntervalMs = DEFAULT_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS;
|
|
for (const candidate of intervalCandidates) {
|
|
const parsed = parseBatchDispatchIntervalCandidate(candidate);
|
|
if (parsed !== null) {
|
|
batchDispatchIntervalMs = parsed;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (batchDispatchIntervalMs === DEFAULT_CANVAS_IMAGE_BATCH_DISPATCH_INTERVAL_MS) {
|
|
for (const candidate of intervalSecondsCandidates) {
|
|
const parsed = parseBatchDispatchIntervalCandidate(candidate, {
|
|
treatAsSeconds: true,
|
|
});
|
|
if (parsed !== null) {
|
|
batchDispatchIntervalMs = parsed;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
concurrency,
|
|
batchDispatchIntervalMs,
|
|
};
|
|
}
|