Repository navigation
Requeue a job inline when its status write-back fails (#1106) - #1219
Closed
rollroyces wants to merge 1 commit into
Closed
rollroyces wants to merge 1 commit into
rollroyces wants to merge 1 commit into
Conversation
Signed-off-by: Royce Lam <roycelam@umich.edu>
Contributor
|
感谢继续跟进 #1106。 这一条我们还是关闭,原因和 #1208 一样:#1106 已经由 #1137 修复并合入 Snowflake 和 Databricks 的测试已经通过 #1221 合入(保留了你的提交,我们只补了一次 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
run_workerwrites the result back viamark_doneormark_failed. Ifthat DB update fails, the row stays in
running. Restoring the databasedoes not recover the work while the worker keeps running:
requeue_failedmatches onlystatus = 'failed', and the startup orphansweep fires only on process restart. Restart requeues the row but
re-runs the same handler — a successful extraction is recomputed from
scratch.
The fix is an inline requeue on the same write-back-failure path.
Persist the state, not the handler run: roll the row back from
runningtoqueuedso the next loop picks it up and tries the statuswrite again. Handlers are documented as idempotent, so re-running them
is a side concern, not a correctness concern.
What changes
crates/utopia-store/src/jobs.rs:new
requeue_running_after_write_failure(pool, id)— single SQLupdate:
UPDATE jobs SET status='queued', locked_at=NULL, run_at=now(), updated_at=now() WHERE id = $1 AND status = 'running'.The
status = 'running'guard is intentional: if anyone else hasalready moved this row out of
running(admin, manualrequeue_failed, sibling worker in a multi-instance deployment), wedon't clobber their decision.
run_at = now()means the next looptick picks it up immediately, with no extra backoff — this is the
persistence path, not the handler-attempt path, so it shouldn't
inflate a
30s × attempts²retry curve.run_worker— whenmark_done/mark_failedreturnsErr, logthe write-back failure as before, then call the new helper. If that
also fails, log both errors together. The
runningcount isdecremented in either case so the worker doesn't bleed a concurrency
slot.
Why v2
The previous attempt (#1208) was based on a fork
c9760a1that haddiverged from
upstream/dev(now25fa9f4, rc9 + ~20 commits). Thepatch is the same — one new helper, one call-site change. The point
of v2 is that the PR now applies on top of the current dev tree
rather than a stale snapshot.
What this proposal does not do
No retry loop around
mark_done/mark_failed. The bug is "rowstuck in
running", the fix is "get it back toqueued". Addingretries here would mean deciding how many and on which schedule —
this PR keeps that decision with whoever owns the backoff curve
(the existing one around handler retries).
No interaction with
requeue_failed. That admin path is opt-in("you've paid attention, retry these specific failures"); the new
fallback is automatic ("we just couldn't persist, retry without
human"). They share the target state (
queued) but fire ondisjoint conditions.
No tests. The existing jobs integration tests need a real
Postgres (
UTOPIA_DATABASE_URL); the project'stest_db::url()skips cleanly when unset. A wire-level test that simulates a
dropped write would require injecting failure into
sqlx::query(..).execute(..), which is a follow-up the maintainermay want to scope.
Verification
cargo check -p utopia-storedid not finish in the local sandbox:the dev-deps chain takes 20+ minutes on the external FUSE mount.
The diff is one new helper function (8 lines of SQL inside a
function) and one call-site addition. Both are pure additions
that should pass
checkfirst try.The maintainer team's feedback on PR Add ClickHouse engine + Snowflake/Databricks boundary tests + Excel ISO-8601 dates #1200 also applies here:
this PR is scoped to one issue (Jobs remain running after failed result writes until the worker restarts #1106), <500 lines, branched off
current
dev, every commit signed off.Tracking