fix(triage): respect global concurrency limit before queuing tasks

The triage processor was kicking off all eligible tasks simultaneously,
queuing them all on the semaphore regardless of available slots. Now it
checks semaphore.availableCount first and only starts as many triage
tasks as there are free slots. Remaining tasks get picked up on the
next poll cycle (default 10-15s) as slots free up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-13 15:06:29 -07:00
parent a8bc136ec4
commit 8124f10511

View File

@@ -474,8 +474,16 @@ export class TriageProcessor {
&& !(t.nextRecoveryAt && new Date(t.nextRecoveryAt).getTime() > now),
);
for (const task of triageTasks) {
void this.specifyTask(task);
// Respect the global concurrency limit — only kick off as many triage
// tasks as the semaphore has available slots. Without this gate, all
// eligible tasks queue on the semaphore simultaneously, which is
// wasteful and confusing in the UI.
const maxToStart = this.options.semaphore
? Math.max(0, this.options.semaphore.availableCount)
: triageTasks.length;
for (let i = 0; i < Math.min(triageTasks.length, maxToStart); i++) {
void this.specifyTask(triageTasks[i]);
}
} catch (err) {
triageLog.error("Poll error:", err);