feat(router): add agent-type concurrency limiting#634
Merged
zbigniewsobiecki merged 1 commit intodevfrom Mar 7, 2026
Merged
Conversation
Add per-agent-type concurrency limits to prevent multiple instances of the same agent type running simultaneously for a project. Core implementation: - New `agent_configs.max_concurrency` column with CHECK constraint - Two-layer lock in `src/router/agent-type-lock.ts`: 1. In-memory concurrency map (fast path, TTL safety net) 2. DB count of running `agent_runs` (authoritative, survives restarts) - Trigger-level dedup (60s TTL) suppresses batch webhook re-triggers - Shared `checkAgentTypeConcurrency()` consolidates logic from 3 handlers Key design decisions: - Use `Math.max(dbCount, inMemoryCount)` instead of sum to avoid double-counting during the enqueued→running transition - 5-second TTL cache on `getMaxConcurrency()` DB queries - Graceful fallback (no limit) when DB is unreachable - Periodic cleanup of dedup map when it exceeds 100 entries Dashboard & CLI: - Agent config forms expose Max Concurrency field - `cascade agents create/update --max-concurrency N` - Agent configs table shows concurrency column Container manager: - `extractAgentType()` handles both trigger-based and dashboard jobs - Worker cleanup releases agent-type locks on exit - `detachAll()` clears all agent-type locks on shutdown Tests: 24 unit tests for agent-type-lock, concurrency-blocked tests added to all 3 webhook handler test suites (3868 total tests passing). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
agent_configs.max_concurrency(DB column, dashboard UI, CLI)checkAgentTypeConcurrency()eliminates code duplication across 3 webhook handlersCode review fixes included
This PR also incorporates fixes from a thorough code review of the initial implementation:
isAgentTypeLockednow usesMath.max(dbCount, inMemoryCount)instead of summing, preventing false positives during the enqueued→running transitionrouterConfig.workerTimeoutMs(module-level constant never throws)checkAgentTypeConcurrency— extracted shared function, deleted 3 near-identical copiesextractAgentType()now checkstriggerResult?.agentTypethen falls back to top-levelagentTypegetMaxConcurrency()DB failures are caught gracefully (proceeds without limit)getMaxConcurrency()to reduce DB queries on webhook batchescheckAgentTypeConcurrencytestsmakeConcurrencyKey/makeDedupKeyinto singlemakeKeymax_concurrency IS NULL OR max_concurrency > 0in migrationTest plan
npm run typecheck— cleannpm run lint— cleannpx vitest run tests/unit/router/agent-type-lock.test.ts— 24 tests passnpm test— full suite 3868 tests pass🤖 Generated with Claude Code