refactor(queue): extract transient-lock primitives into their own module - #4157
Conversation
Step 1 of a ~10-step sequence to split src/queue/processors.ts (14000+ lines) into cohesive modules. Moves the generic transient-lock primitive (claimTransientLock/releaseTransientLockIfOwner/TransientLockClaim) and the per-PR actuation-lock domain wrapper built on it into src/queue/transient-locks.ts -- a pure structural move, no logic changes. The AI-review-lock domain wrapper (a second consumer of the same primitive) stays in processors.ts for now and imports the primitive back from the new module; its own extraction is a later step in the sequence. A temporary re-export shim keeps test/unit/queue.test.ts's existing import path working -- those tests are deeply interspersed with unrelated ones, not in a cleanly extractable block, so relocating them is deferred.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4157 +/- ##
=======================================
Coverage 93.73% 93.73%
=======================================
Files 386 387 +1
Lines 36304 36304
Branches 13298 13298
=======================================
+ Hits 34029 34031 +2
+ Misses 1618 1617 -1
+ Partials 657 656 -1
🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-08 08:32:40 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 5 non-blocking
Concerns raised — review before merging
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
…le (#4820) Part of #4013's module-split sequence (step 2, after transient-locks.ts in #4157): generateSignalSnapshots and its loadOpenQueueCounts helper move to src/queue/signal-snapshot.ts. Pure mechanical move, no behavior change -- a re-export shim keeps processors.ts's existing external callers (src/api/routes.ts, test/unit/queue-trends.test.ts) working unchanged.
Summary
src/queue/processors.ts(14,000+ lines, growing fast under this repo's high commit velocity — expect the issue's own cited line numbers to be stale) into cohesive modules. Only step 1 is attempted here, per the issue's own recommended sequencing and this repo's small-PR house style — the remaining steps are separate, later PRs.flag_management/carryforward/rename-specific setting exists incodecov.yml— patch coverage is computed straight off the diff. Rather than gamble the PR's mergeability on unconfirmed rename detection, this extraction is structured as a literal move (identical code,exportadded only where a name crosses the new module boundary) AND ships with genuinely complete, direct test coverage regardless of how Codecov scores the diff.claimTransientLock/releaseTransientLockIfOwner/TransientLockClaim(the generic best-effort exclusive-lock primitive) and the per-PR actuation-lock domain wrapper built on it (claimPrActuationLock/releasePrActuationLock/PrActuationLockContendedError) into a newsrc/queue/transient-locks.ts. Zero logic changes — this is a pure structural move.claimTransientLock/releaseTransientLockIfOwner/TransientLockClaimprimitive with a SECOND consumer, the per-(repo, PR, head SHA, mode) AI-review lock (claimAiReviewLock/releaseAiReviewLock), which stays inprocessors.ts. Extracting just the actuation-lock wrapper alone would have required either code duplication or a circular import (transient-locks.ts→processors.ts→transient-locks.ts). Moving the shared primitive alongside its first consumer, with the second consumer importing it back, avoids both — and conveniently anticipates the issue's own laterai-review-orchestration.tsstep, which is presumably whereclaimAiReviewLock/releaseAiReviewLockwill eventually land.export { claimPrActuationLock, releasePrActuationLock } from "./transient-locks";) keepstest/unit/queue.test.ts's existingimport { ... } from "../../src/queue/processors"working unchanged. Those specific tests are individualit()blocks deeply interspersed with ~20 unrelated tests in the same file, not inside a cleanly extractabledescribeblock — relocating them is deliberately deferred rather than forced into this PR (splittingtest/unit/queue.test.tsitself is also outside refactor(queue): split processors.ts into cohesive modules #4013's literal scope, which is aboutsrc/queue/processors.ts).Scope
CONTRIBUTING.md.Validation
git diff --checknpm run typechecknpm run db:migrations:check/npm run db:schema-drift:check— no-ops confirmed (no DB schema touched).npx vitest run test/unit/queue.test.ts test/unit/transient-locks.test.ts— 707/707 passing.src/queue/transient-locks.ts: 100% statements/branches/functions/lines. Two new dedicated tests intest/unit/transient-locks.test.tsclose a real, pre-existing gap the extraction exposed (not introduced): every existing "cache.claim()throws" test inqueue.test.tsuses a mock cache that omitsreleaseIfValue, so it hitsclaimTransientLock's earlier!cache.releaseIfValuefail-open guard and never actually reaches thetry/catcharoundcache.claim()itself — invisible before because it was diluted insideprocessors.ts's aggregate coverage; now that this is a standalone file, patch coverage requires it closed. Same story forreleaseTransientLockIfOwner's!cache?.releaseIfValueearly-return branch. Both gaps closed with minimal, targeted tests; the existing ~20 indirect tests inqueue.test.ts(unmoved) provide the rest of the module's real coverage for free, confirming the extraction didn't change behavior.npm run test:workers,build:mcp,test:mcp-pack,ui:openapi:check,ui:lint,ui:typecheck,ui:build,npm audit— not re-run locally (no worker/MCP/OpenAPI/UI-component code touched); CI runs them authoritatively.Safety
queue.test.tssuite passing unchanged.Notes
signal-snapshot.tsnext (the other self-contained "prove the pattern" candidate the issue names), thenduplicate-detection.ts,slop-detection.ts,review-evasion.ts,ci-resolution.ts,retention.ts, then the interdependent triogate-checks.ts/ai-review-orchestration.ts/job-dispatch.tslast (the AI-review-lock wrapper likely moves as part of that last group).processors.ts), each subsequent step in this sequence should re-derive its own boundary at the time it's picked up rather than trusting this PR's snapshot of the file.