factory: reclaim seeds stuck in 'discovering' after 15 min (process restarts during deploys)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2 changed files +2 −2
modified
apps/engine/src/factory-main.ts
+1 −1
@@ -112,7 +112,7 @@ async function main(): Promise<void> { | ||
| 112 | 112 | clearInterval(timer); |
| 113 | 113 | const deadline = Date.now() + 90_000; |
| 114 | 114 | while (inflight > 0 && Date.now() < deadline) await new Promise((r) => setTimeout(r, 250)); |
| 115 | − // Seeds still marked `discovering` are reclaimed automatically after 2 h (claim query). | |
| 115 | + // Seeds still marked `discovering` are reclaimed automatically after 15 min (claim query; per-seed deadline is 2 min). | |
| 116 | 116 | await closeDispatcher(); |
| 117 | 117 | await closeRedis(); |
| 118 | 118 | await closeDb(); |
modified
apps/engine/src/factory/run.ts
+1 −1
@@ -220,7 +220,7 @@ export async function claimSeeds(n: number, opts: { seedIds?: string[] } = {}): | ||
| 220 | 220 | update factory_seeds set status = 'discovering', attempts = attempts + 1, updated_at = now() |
| 221 | 221 | where id in ( |
| 222 | 222 | select id from factory_seeds |
| 223 | − where ${opts.seedIds ? sql`id = any(${sql.raw("array[" + opts.seedIds.map((i) => "'" + i.replace(/'/g, "''") + "'").join(",") + "]::text[]")})` : sql`(status = 'queued' or (status = 'error' and attempts < 3 and updated_at < now() - interval '6 hours') or (status = 'discovering' and updated_at < now() - interval '2 hours'))`} | |
| 223 | + where ${opts.seedIds ? sql`id = any(${sql.raw("array[" + opts.seedIds.map((i) => "'" + i.replace(/'/g, "''") + "'").join(",") + "]::text[]")})` : sql`(status = 'queued' or (status = 'error' and attempts < 3 and updated_at < now() - interval '6 hours') or (status = 'discovering' and updated_at < now() - interval '15 minutes'))`} | |
| 224 | 224 | order by importance desc, created_at asc limit ${n} for update skip locked) |
| 225 | 225 | returning *`); |
| 226 | 226 | return claimed.rows.map(normalizeSeed); |
| 227 | 227 | |