feat(KB-152): make triage poll() dispatch specifyTask() calls concurrently

- Change poll() to fire specifyTask() with `void` instead of `await`, enabling concurrent task specification bounded by AgentSemaphore
- Add JSDoc to poll() documenting concurrent dispatch and re-entrance guard behavior
- Add tests for concurrent dispatch, semaphore limiting, polling flag reset, and overlapping poll discovery
- Update existing re-entrance guard test to block on listTasks (discovery) rather than specifyTask
- Fix existing paused-tasks and globalPause tests for non-blocking dispatch timing
This commit is contained in:
Dustin Byrne
2026-03-28 02:31:41 -04:00
parent b0d361cc3c
commit 0a5b1ed76f
2 changed files with 212 additions and 33 deletions

View File

@@ -267,6 +267,16 @@ export class TriageProcessor {
triageLog.log(`Poll interval updated to ${newIntervalMs}ms`);
}
/**
* Discover triage tasks and dispatch `specifyTask()` for each one.
*
* **Concurrent dispatch:** `specifyTask()` calls are fired without awaiting,
* so multiple triage tasks can be specified concurrently (bounded by the
* shared `AgentSemaphore`). The `polling` re-entrance guard prevents
* overlapping discovery cycles, but resets as soon as dispatch completes —
* well before the dispatched tasks finish — so subsequent polls can discover
* newly arrived triage tasks promptly.
*/
private async poll(): Promise<void> {
if (!this.running) return;
if (this.polling) return;
@@ -292,7 +302,7 @@ export class TriageProcessor {
);
for (const task of triageTasks) {
await this.specifyTask(task);
void this.specifyTask(task);
}
} catch (err) {
triageLog.error("Poll error:", err);