mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
fix(minions): give facts-absorb the 10-min handler-timeout default (#3207)
Add 'facts-absorb' to HANDLER_DEFAULT_TIMEOUT_MS (same one-page-one-LLM-call shape as chronicle_extract) and drop the hardcoded 180s timeout_ms on the durable backstop submit so the submit-time map stamp applies — an explicit opts.timeout_ms always wins, which would have neutralized a map-only fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e79b8d5780
commit
1afae80f7a
@@ -191,7 +191,9 @@ export async function runFactsBackstop(
|
||||
// identical writes (idempotent ON CONFLICT returns existing row).
|
||||
idempotency_key: `facts-absorb:${ctx.sourceId}:${parsedPage.slug}:${contentHash}`,
|
||||
max_attempts: 3,
|
||||
timeout_ms: 180_000,
|
||||
// No explicit timeout_ms: let MinionQueue.add stamp the
|
||||
// handler-timeouts.ts default (#3207 — a hardcoded 180s here
|
||||
// overrode the map and wall-clock-killed slow-gateway absorbs).
|
||||
},
|
||||
);
|
||||
return { mode: 'queue', enqueued: true, queueDepth: 0 };
|
||||
|
||||
@@ -43,6 +43,9 @@ export const HANDLER_DEFAULT_TIMEOUT_MS: Readonly<Record<string, number>> = {
|
||||
// few writes. Generous 10-min budget (vs the tight null-default) covers a
|
||||
// slow gateway without the 30-min loop budget.
|
||||
chronicle_extract: TEN_MIN_MS,
|
||||
// #3207 — facts absorb: same one-page-one-LLM-call shape as
|
||||
// chronicle_extract; a slow gateway must not wall-clock-kill it.
|
||||
'facts-absorb': TEN_MIN_MS,
|
||||
// Per-page contextual reindex jobs process chunks sequentially with one
|
||||
// rate-leased LLM synopsis call per chunk; large transcript pages need more
|
||||
// than the standard 30-min long-job budget.
|
||||
|
||||
@@ -301,3 +301,36 @@ describe('runFactsBackstop — stub guard routing (v0.34.5)', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#3207 — durable facts-absorb submit uses the handler-timeout map', () => {
|
||||
test('defaultTimeoutMsFor stamps facts-absorb with the 10-min budget (matches chronicle_extract)', async () => {
|
||||
const { defaultTimeoutMsFor } = await import('../src/core/minions/handler-timeouts.ts');
|
||||
expect(defaultTimeoutMsFor('facts-absorb')).toBe(10 * 60 * 1000);
|
||||
expect(defaultTimeoutMsFor('facts-absorb')).toBe(defaultTimeoutMsFor('chronicle_extract'));
|
||||
});
|
||||
|
||||
test('short-lived CLI durable submit inherits the map default (no hardcoded 180s override)', async () => {
|
||||
const { markShortLivedCliProcess, __resetShortLivedCliForTests } =
|
||||
await import('../src/core/facts/cli-process-mode.ts');
|
||||
markShortLivedCliProcess();
|
||||
try {
|
||||
const page = meetingPage();
|
||||
const r = await runFactsBackstop(page, makeCtx());
|
||||
expect(r.mode).toBe('queue');
|
||||
if (r.mode === 'queue') expect(r.enqueued).toBe(true);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const rows = await (engine as any).db.query(
|
||||
`SELECT timeout_ms FROM minion_jobs WHERE name = 'facts-absorb' AND data->>'slug' = $1`,
|
||||
[page.slug],
|
||||
);
|
||||
expect(rows.rows.length).toBe(1);
|
||||
// Submit-time stamp comes from HANDLER_DEFAULT_TIMEOUT_MS, not the old
|
||||
// hardcoded 180_000 that overrode any map-only fix (the map's contract:
|
||||
// "An explicit opts.timeout_ms always wins").
|
||||
expect(Number(rows.rows[0].timeout_ms)).toBe(10 * 60 * 1000);
|
||||
} finally {
|
||||
__resetShortLivedCliForTests();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user