feat(miner): add lease + expiry sweep to reclaim stuck portfolio-queue items - #5202
Conversation
|
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 #5202 +/- ##
=======================================
Coverage 94.35% 94.35%
=======================================
Files 473 473
Lines 39977 39977
Branches 14574 14574
=======================================
Hits 37719 37719
Misses 1585 1585
Partials 673 673
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-12 09:39:47 UTC
⏸️ Suggested Action - Manual Review Review summary Blockers
Nits — 5 non-blocking
Review context
Contributor next steps
Signal definitions
[BETA] Chat with GittensoryAsk Gittensory a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/gittensory-commands 🟩 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.
|
|
An AI reviewer flagged a likely defect, but its confidence was below this repository's configured close-confidence floor, so this is held for a maintainer to confirm instead of closing automatically. Resolve the flagged defect (see the review notes), or ask a maintainer to override. |
d421374 to
b379803
Compare
|
Gittensory is closing this pull request on the maintainer's behalf (conflicts with the base branch — resolve and open a fresh PR). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed. |
JSONbored
left a comment
There was a problem hiding this comment.
Fix merge conflict, bot merged one of my PRs before yours accidentally
b379803 to
c3ce33a
Compare
|
Thanks for the heads-up! Rebased onto latest |
…e items Portfolio-queue items were flipped to in_progress with no lease and no expiry, so a crashed or killed process stranded an item in_progress forever with no recovery — unlike the claim-ledger and worktree-allocator stores in the same package, which already sweep their own stuck rows. Adds a leased_at column (idempotently migrated onto existing stores) stamped when an item is claimed and cleared when it leaves in_progress, a listInProgress()/reclaimStuckItem() pair on the store, and a pure portfolio-queue-expiry module (findStuckItems + sweepStuckItems) mirroring claim-ledger-expiry. The base QueueEntry shape every existing caller relies on is unchanged; lease data is exposed via a separate projection. Closes JSONbored#4827
c3ce33a to
3aae12d
Compare
Summary
Portfolio-queue items were flipped to
in_progresswith no lease and no expiry sweep, so a crashed or killed process left an item stuckin_progressforever with no automated recovery — unlike the sibling stores in the same package (claim-ledgerandworktree-allocator), which already solve exactly this for their own tables.This adds a lease + expiry sweep to the portfolio-queue store, mirroring the existing
claim-ledger-expirypattern:leased_atcolumn onminer_portfolio_queue, stamped with the claim time when an item is flipped toin_progress(bothdequeueNextandbatchClaim) and cleared back toNULLwhen it leavesin_progress(done / failed / reclaimed). Idempotently migrated onto pre-existing stores (CREATE TABLE IF NOT EXISTSnever adds a column, so a guardedALTER TABLE ... ADD COLUMN).store.listInProgress()(lease-annotated rows) andstore.reclaimStuckItem()(atomicin_progress → queued, clearing the lease) — the store half of the sweep.portfolio-queue-expiry.js— a pure module (findStuckItems+sweepStuckItems), a direct mirror ofclaim-ledger-expiry.js: reclaim in-flight items whose lease age strictly exceeds a bound (default 30 min), leaving fresh / non-in_progress/ unparseable-lease rows untouched.The base
QueueEntryshape every existing caller relies on is unchanged — lease data rides a separateQueueLeaseEntryprojection — so no existing consumer or test changes.Anchored on two existing analogues in the same package:
claim-ledger-expiry.js(the sweep shape) andworktree-allocator.js/claim-ledger.js(the store-level expiry the issue cites).Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #4827.Validation
git diff --checknpm run build:miner(node --check, incl. the newportfolio-queue-expiry.js)npm run test:miner-pack(tarball hygiene — newlib/portfolio-queue-expiry.{js,d.ts}packaged)npx vitest runon the changed area — 41 tests pass: the newminer-portfolio-queue-expirysuite (10) plus the existing portfolio-queue store / manager / CLI suites (no regressions)typecheckclean on the changed files (.d.ts+ test)If any required check was skipped, explain why:
packages/gittensory-miner/lib/**(hand-written ESM.js+.d.ts, validated vianode --check, nottsc) andtest/unit/**. Nosrc/**, UI, MCP, workflow, migration, or dependency changes — Codecov ignores this path (nosrc/**touched), and the backend/UI/MCP CI jobs are path-skipped.Safety
Notes
PortfolioQueueManager:claimNextBatch()reclaims orphaned leases back toqueuedbefore selecting, so a crashed process's stuck item becomes eligible again instead of permanently occupying a WIP slot. Also exposed asmanager.reclaimStuckItems(maxLeaseMs?)and configurable via thestaleLeaseMsoption (default 30 min). The puresweepStuckItems/findStuckItemsmodule stays IO/Date-free (mirroringclaim-ledger-expiry); the manager suppliesDate.now()at the boundary.leasedAtis never swept.Closes #4827