fix(vector): retry transient embed errors so a pod rollover drops 0 docs
From card 309 (OHR-Bench smoke-test triage): during a backend-pod rollover the
embedding endpoint was briefly unreachable, and openai.APIConnectionError /
ConnectError propagated unretried (the provider only retried 429). Documents
exhausted the 3 in-process retries and were dropped for that scan cycle.
Broaden the provider-level retry to the transient set -- APIConnectionError,
APITimeoutError, 429, and 5xx -- on the existing exponential backoff (2s->60s,
5 attempts), so a few seconds of retry rides through the rollover. Permanent
4xx (auth, bad request) still re-raise immediately. Generalize the shared
_retry helper (retry_on_rate_limit -> retry_on_transient, predicate renamed to
should_retry, accurate log label) with a back-compat alias; Mistral gets 429+5xx
for parity. The production gateway path inherits this via GatewayProvider, which
delegates to the decorated OpenAIProvider methods.
Add astrolabe_vector_ingest_dropped_total{reason}, incremented when a document
exhausts retries, classified (connection|timeout|rate_limit|server|qdrant|other)
by _drop_reason so the embed-drop rate is alertable per cause. Dropped docs are
NOT marked failed, so the next full scan re-picks them (re-queue via scan loop).
Refs: Deck board 12 card 309 (AC #1 no permanently-dropped docs; embed-drop
metric for AC #5).
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
457c115ef4
commit
258ee96f4c
@@ -161,6 +161,18 @@ vector_sync_processing_duration_seconds = Histogram(
|
||||
buckets=(0.1, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0, 60.0),
|
||||
)
|
||||
|
||||
# Documents dropped after exhausting in-process indexing retries (the scanner
|
||||
# re-picks them on a later full scan, so this is "dropped for this cycle", not
|
||||
# "lost forever"). Labelled by classified cause so the embed-drop rate from a
|
||||
# transient backend-pod rollover (connection/timeout) is alertable distinctly
|
||||
# from a persistent fault (card 309). astrolabe_ prefix: pipeline metric.
|
||||
vector_ingest_dropped_total = Counter(
|
||||
"astrolabe_vector_ingest_dropped_total",
|
||||
"Documents dropped after exhausting indexing retries, by cause",
|
||||
# reason: connection | timeout | rate_limit | server | qdrant | other
|
||||
["reason"],
|
||||
)
|
||||
|
||||
vector_sync_queue_size = Gauge(
|
||||
"mcp_vector_sync_queue_size",
|
||||
"Current number of documents in processing queue",
|
||||
@@ -692,6 +704,16 @@ def record_document_parse_failed(reason: str) -> None:
|
||||
document_parse_failed_total.labels(reason=reason).inc()
|
||||
|
||||
|
||||
def record_ingest_dropped(reason: str) -> None:
|
||||
"""Record a document dropped after exhausting in-process indexing retries.
|
||||
|
||||
Args:
|
||||
reason: ``connection`` | ``timeout`` | ``rate_limit`` | ``server`` |
|
||||
``qdrant`` | ``other`` (classified from the terminal exception).
|
||||
"""
|
||||
vector_ingest_dropped_total.labels(reason=reason).inc()
|
||||
|
||||
|
||||
def record_document_classification(
|
||||
recommended_tier: str,
|
||||
flags: set[str],
|
||||
|
||||
Reference in New Issue
Block a user