fix(ingest): address review round 2 (stale gauge + hygiene)
- metrics: update_ingest_queue_depth now pre-zeroes every managed ingest queue before applying live counts, so a queue that drains to empty (and drops out of procrastinate's list_queues_async) reads 0 instead of sticking at its last non-zero value (ghost backlog in Grafana/alerts). Adds a regression test. - procrastinate: comment that _is_transient_infra_error treats all qdrant errors as transient deliberately (bounded same-tier retry; over-broad is acceptable). - escalation: note next_tier is the building block; production routing uses ProcessorRegistry.next_available_tier. - tests: add evaluate_escalation fast+ocr-only low-confidence -> ocr case. Deck #323. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
35f8204a16
commit
e7c0c23486
@@ -279,6 +279,13 @@ def _is_transient_infra_error(exc: BaseException) -> bool:
|
||||
return exc.status_code >= 500
|
||||
except ImportError: # pragma: no cover -- openai is a hard dependency
|
||||
pass
|
||||
# Deliberately over-broad: this treats ALL qdrant_client exceptions as
|
||||
# transient (not just timeouts/5xx). In a healthy cluster qdrant errors are
|
||||
# transient, and a bounded same-tier retry is cheap; a genuinely permanent
|
||||
# qdrant fault (e.g. schema mismatch) just exhausts the transient cap and
|
||||
# then gives up. So unlike _drop_reason (which only *labels* the cause), this
|
||||
# may add a few retries on a non-retriable qdrant error -- an acceptable
|
||||
# trade for not having to enumerate qdrant's non-retriable status codes.
|
||||
if type(exc).__module__.startswith("qdrant_client"):
|
||||
return True
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user