Repository navigation
fix(models): race-free lazy encoder load; timeout and length check for model downloads - #374
Merged
Merged
Conversation
…r model downloads OnnxEncoder._load (#340): the unlocked fast path only checked _session, and _session was assigned before Tokenizer.from_file ran. A concurrent encode_texts on the shared encoder could skip loading and call encode_batch on a None tokenizer. The session and tokenizer are now built into locals and published tokenizer-first, session-last. Both the fast path and the in-lock re-check require both attributes to be set. A failed tokenizer load leaves the encoder unloaded so a retry works. fd.models.pull (#341): _fetch called urlopen with no timeout and copied the body without checking its length. A stalled mirror blocked forever, and a connection closed early installed a truncated file. _fetch now passes timeout=FRESHDATA_MODEL_TIMEOUT (default 60 seconds; a non-numeric, non-finite or non-positive value raises ValueError). It counts the bytes written and raises OSError when the count differs from Content-Length. pull()'s existing cleanup removes the .part file, so nothing is installed. FRESHDATA_MODEL_TIMEOUT is documented in docs/semantic-models.md. Closes #340 Closes #341
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
FreshData benchmark report —
|
| fixture | n_rows | n_cols | p50 s | p95 s | peak MB | repair % | false-repair % | preserve % | trust | monotonic | export % |
|---|
Authored-code reduction (Metric 6)
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.
Summary
OnnxEncoderlazy-load race._loadchecked only_sessionoutside the lock and set_sessionbefore loading the tokenizer, so a concurrentencode_textscould callencode_batchonNone. The session and tokenizer are now built as local variables and assigned tokenizer first, session last. The check outside and inside the lock requires both. A failed tokenizer load leaves the encoder unloaded, so the next call retries.fd.models.pulltruncation and timeout._fetchnow passestimeout=tourlopen(fromFRESHDATA_MODEL_TIMEOUT, default 60 s; a non-numeric, non-finite or non-positive value raisesValueError). It counts the bytes written and raisesOSError("incomplete download of <url>: got N of M bytes")when the count differs fromContent-Length. The existing cleanup inpull()removes the.partfile, so nothing is installed. Checksum handling and the URLs fetched are unchanged.FRESHDATA_MODEL_TIMEOUTindocs/semantic-models.md.Note:
freshdata models pullon the CLI still only catchesModelError, so a truncated download or invalid timeout ends in a traceback there, as network errors already did.Tests
New
tests/test_models_download_robustness.py, fully offline:onnxruntime/tokenizersmodules injected throughsys.modules. A second thread is started while the first is still insideTokenizer.from_file; it waits instead of crashing, and the model loads once. There is also an 8-threadBarriertest, a check that a session without a tokenizer triggers a load, and a retry after a failed load.urllib.request.urlopenresponse covering: a truncated body raisesOSErrorand leaves no final file, no.partfile andinstalled=False; a full download over several read chunks installs; a response without Content-Length is accepted; the default and overridden timeouts are passed tourlopen; invalid timeout values raiseValueErrorbefore any network call; a timeout error leaves no.partfile.Verification
ruff check .clean;mypy src/freshdataclean (202 files)Closes #340
Closes #341