fix: clamp fractional automation queue limits

This commit is contained in:
Sucukdeluxe
2026-08-26 09:02:19 +02:00
parent 41ae750e97
commit 4d0b58285f
2 changed files with 23 additions and 2 deletions
+2 -2
View File
@@ -21,8 +21,8 @@
if (isString && value.trim() === '') return 15000; if (isString && value.trim() === '') return 15000;
const number = Number(value); const number = Number(value);
if (!Number.isFinite(number) || number < 0) return 15000; if (!Number.isFinite(number) || number < 0) return 15000;
if (number === 0 && isString && value.trim() !== '0') return 15000; if (number === 0) return isString && value.trim() !== '0' ? 15000 : 0;
return Math.floor(number); return Math.max(1, Math.floor(number));
} }
function normalizeAutomationSettings(value = {}) { function normalizeAutomationSettings(value = {}) {
+21
View File
@@ -59,6 +59,13 @@ test('automation settings allow only numeric and trimmed string zero to disable
assert.equal(normalizeAutomationSettings({ queueLimitJobs: ' 0 ' }).queueLimitJobs, 0); assert.equal(normalizeAutomationSettings({ queueLimitJobs: ' 0 ' }).queueLimitJobs, 0);
}); });
test('automation settings clamp positive queue limit fractions to one', () => {
assert.deepEqual(
[0.5, '0.5', 0.125].map((queueLimitJobs) => normalizeAutomationSettings({ queueLimitJobs }).queueLimitJobs),
[1, 1, 1]
);
});
test('capacity counts only executable and running queue jobs', () => { test('capacity counts only executable and running queue jobs', () => {
const statuses = ['preview', 'queued', 'getting-server', 'uploading', 'retrying', 'done', 'error', 'aborted', 'skipped']; const statuses = ['preview', 'queued', 'getting-server', 'uploading', 'retrying', 'done', 'error', 'aborted', 'skipped'];
assert.equal(countAutomaticQueueJobs(statuses.map((status, index) => ({ id: String(index), status }))), 5); assert.equal(countAutomaticQueueJobs(statuses.map((status, index) => ({ id: String(index), status }))), 5);
@@ -146,6 +153,20 @@ test('admission allows only numeric and trimmed string zero to disable the queue
); );
}); });
test('admission keeps positive queue limit fractions bounded to one job', () => {
const candidate = { path: 'two-jobs.mkv', mtimeMs: 1, eligibleJobCount: 2 };
assert.deepEqual(
[0.5, '0.5', 0.125].map((queueLimitJobs) => planAtomicAdmissions({ candidates: [candidate], queueLimitJobs })),
[0.5, '0.5', 0.125].map(() => ({
admittedPaths: [],
deferredPaths: ['two-jobs.mkv'],
currentJobCount: 0,
plannedJobs: 0,
availableSlots: 1
}))
);
});
test('daily telemetry resets atomically on the local calendar day boundary', () => { test('daily telemetry resets atomically on the local calendar day boundary', () => {
const before = { dateKey: '2026-08-25', detected: 8, queued: 4, skipped: 2, deferred: 1 }; const before = { dateKey: '2026-08-25', detected: 8, queued: 4, skipped: 2, deferred: 1 };
const now = new Date(2026, 7, 26, 0, 0, 1).getTime(); const now = new Date(2026, 7, 26, 0, 0, 1).getTime();