cold_clone: JIT hydrate skips missing/mismatched blobs (no crash)

Partial Tier B snapshots (where the producer didn't upload every
chunk, e.g. due to the corpus's BLOB-vs-TEXT-affinity skew) left
some NULL chunks without a corresponding blob in the bucket.
hydrate_doc_jit used to raise on the first NoSuchKey / hash
mismatch, which collapsed the whole JIT query. Now we skip the
offending chunk and let the query path see the same NULL content
it would see on a cold shard. Worst case: partial context, not a
crashed query.
This commit is contained in:
russell@unturf.com 2026-05-30 06:56:03 -04:00
parent 7ada42823f
commit 9c747ad862
No known key found for this signature in database

View file

@ -414,26 +414,31 @@ def hydrate_doc_jit(
if not rows:
return 0
def _fetch(pair: tuple[int, str]) -> tuple[int, bytes]:
def _fetch(pair: tuple[int, str]):
chunk_id, leaf_hash = pair
key = f"{BLOB_PREFIX}/{leaf_hash[:2]}/{leaf_hash[2:]}"
body = backend.get(key)
try:
body = backend.get(key)
except Exception:
# Blob missing or unreadable — skip this chunk. The query
# path will see content still NULL and behave as it would
# for a cold shard (graceful degradation, not a crash).
return None
if hash_leaf(body).hex() != leaf_hash:
raise ValueError(
f"chunk {chunk_id}: bucket blob hash mismatch (leaf_hash {leaf_hash[:12]})"
)
return None
return chunk_id, body
pairs = [(r[0], r[1]) for r in rows]
n_workers = max(1, min(fetch_workers, len(pairs)))
with ThreadPoolExecutor(max_workers=n_workers) as ex:
fetched = list(ex.map(_fetch, pairs))
with conn:
conn.executemany(
"UPDATE chunks SET content = ? WHERE chunk_id = ?",
[(body, cid) for cid, body in fetched],
)
return len(fetched)
results = [r for r in ex.map(_fetch, pairs) if r is not None]
if results:
with conn:
conn.executemany(
"UPDATE chunks SET content = ? WHERE chunk_id = ?",
[(body, cid) for cid, body in results],
)
return len(results)
def fetch_chunk_jit(