Fail interrupted groundings at boot and bound hand grounding
At boot, after the job runner fails the jobs a previous process left running, FailInterruptedGroundings sets every dinner still pending with no ground_dinner job queued or running to failed (interrupted). A crash mid-job, or between saving a dinner and enqueuing its job, no longer leaves the dinner pending forever. A search failure on recipe-candidates or ground now logs only the reason code search_failed, never the wrapped error, which may quote the provider; the response stays redacted. When the grounding job cannot be enqueued, POST /dinners answers 201 with the saved dinner failed (grounding_error) and grounding_job_id null, instead of a 500 that hid the dinner it had created. Grounding a candidate or link by hand runs under a 90-second deadline (fetch, photo, normalize_recipe); past it the request answers 504 ground_timeout and the dinner is unchanged. Maestro task: 0cbaa5bf-8be4-4cbd-aab2-891e7f1bc2b5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -109,3 +109,20 @@ SET grounding_status = 'failed',
|
||||
grounding_error = ?,
|
||||
updated_at = ?
|
||||
WHERE id = ? AND grounding_status = 'pending';
|
||||
|
||||
-- name: FailOrphanedPendingDinnerGroundings :execrows
|
||||
-- Fails every dinner still pending whose grounding job is no longer queued
|
||||
-- or running: the process stopped before the job, or before its handler
|
||||
-- recorded a result. Run at boot, after the job runner fails the jobs a
|
||||
-- previous process left running.
|
||||
UPDATE dinners
|
||||
SET grounding_status = 'failed',
|
||||
grounding_error = sqlc.arg(grounding_error),
|
||||
updated_at = sqlc.arg(updated_at)
|
||||
WHERE grounding_status = 'pending'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM jobs
|
||||
WHERE jobs.kind = sqlc.arg(kind)
|
||||
AND jobs.status IN ('queued', 'running')
|
||||
AND json_extract(jobs.payload, '$.dinner_id') = dinners.id
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user