Repository navigation
Fetch a remote-only series manifest through the custom_file_handler (#87) - #88
Merged
Merged
Conversation
A series document that arrived from a store keeping bytes remote -- a SyncFiles=false round trip through NDI Cloud, say -- lands with its manifest's file_info naming an ndic:// address and no manifest bytes on this machine. _open_series_member's local-only manifest lookup then raised DID:SQLITEDB:FileSeries:ManifestNotLocal without ever offering the manifest's location to the handler, even when the caller had passed one. Port DID-matlab's fix (VH-Lab/DID-matlab#201, PR #202): add SQLiteDB._fetch_series_manifest_bytes -- one level up from the existing _fetch_remote_to_cache with the same call shape. It reads the manifest's file_info straight from the document, offers every non-'file' location to the custom_file_handler with the manifest's uid in the context (seriesName='', mode='open'), and lands the bytes at filecachepath/<manifestUid> under the same single-flight lock the member fetch already holds. Success means the next cached_path_for_uid is a hit, whether the next call is this member, another member of the same series, or a later session. _open_series_member's fast local path is unchanged; the fetch only fires when the manifest is not on disk AND a custom_file_handler was supplied, so exist_doc and the no-handler cases keep their old shape. When the handler cannot service the manifest's location, the existing DID:SQLITEDB:FileSeries:ManifestNotLocal identifier and message are what gets raised, so callers that pattern-match on it keep working. _series_manifest_path stays no-network -- the promise that lets cached_path_for_file resolve files from any thread and any process without holding the database session. The lazy-fetch path lives on the sqlite implementation, where the handler already does. Companion port of VH-Lab/DID-matlab#202. Together they unblock the NDI-matlab workaround in ndi.cloud.sync.internal.updateFileInfoForLocalFiles (which installs a second location on the manifest so the handler has a non-'file' path to resolve) and will let it retire in a follow-up.
CI's lint job (black --check) reformatted src/did/implementations/sqlitedb.py and tests/test_open_doc_file_series.py; no code change, only line breaks. CI's Bridge coverage vs DID-matlab reported drift on database and sqlitedb because DID-matlab#202 landed the port this PR mirrors. Bump both entries' matlab_last_sync_hash to 8bea92c (the merge) and record in sync_notes what was ported. This is the "READ THE DIFF AND PORT THE CHANGE, then set matlab_last_sync_hash to the commit you examined" step -- the diff is the one this PR itself carries, so the notes name it directly. No behavior change from this commit; the port itself is in 449889b.
This was referenced Sep 14, 2026
Merged
Merged
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
Closes #87. Companion port of the DID-matlab fix in VH-Lab/DID-matlab#201 (PR VH-Lab/DID-matlab#202).
A series document that arrived from a store keeping bytes remote — a
SyncFiles=falseround trip through NDI Cloud, say — lands with its manifest'sfile_infonaming anndic://address and no manifest bytes on this machine._open_series_member's local-only manifest lookup then raisedDID:SQLITEDB:FileSeries:ManifestNotLocalwithout ever offering the manifest's location to the handler, even when the caller had passed one.This PR adds a dedicated fetch path so a cloud-only manifest resolves the same way every other remote file already does, without changing the fast local path or the no-network contract of
cached_path_for_file.What changed
SQLiteDB._fetch_series_manifest_bytes(src/did/implementations/sqlitedb.py) — new protected method, one level up from the existing_fetch_remote_to_cachewith the same call shape. Reads the manifest'sfile_infostraight from the document, offers every non-'file'location to thecustom_file_handlerwith the manifest's own uid in the context (seriesName="",mode="open"), and lands the bytes atfilecachepath/<manifestUid>under the same single-flight lock the member fetch already holds. Failure returnsNoneso the caller can raise the ordinaryManifestNotLocal._open_series_member— when_series_manifest_pathreturnsNoneAND acustom_file_handlerwas supplied, calls the helper before raising. Fast local path unchanged;exist_doc, no-handler, and no-remote-location cases still get the sameManifestNotLocalshape as before._series_manifest_path(src/did/database.py) — docstring updated: it is deliberately no-network socached_path_for_filestays callable from any thread and any process, and the retrieval-authorized path lives on the sqlite implementation.Tests (
tests/test_open_doc_file_series.py)New
TestFetchingAnAbsentManifestclass with astored_series_cloud_onlyfixture (ndicloud location,ingest=0— the shapeSyncFiles=falseproduces, uid-keyed handler serves the bytes):test_a_cloud_only_manifest_is_retrieved_through_the_handler— acceptance case. Handler receives the manifest'sndic://sourcePath with the manifest's own uid in the context,ctx.seriesName="",ctx.mode="open"; the member then reads back byte-for-byte.test_the_manifest_lands_at_filecachepath_after_the_fetch— pins the cache placement (filecachepath/<manifestUid>) that makes the second open cheap.test_different_members_share_one_manifest_fetch— three different member opens result in exactly one manifest handler call.test_a_handler_that_serves_nothing_raises_manifest_not_local— handler-refused case still raisesDID:SQLITEDB:FileSeries:ManifestNotLocal, so callers pattern-matching on the identifier keep working.test_no_handler_still_raises_manifest_not_local— the no-handler path is unchanged.All 41 tests in the file pass; the whole suite (
686 passed, 10 skipped, 1 xfailed) passes locally (the bridge-contract module is skipped becausepyyamlisn't installed in the run environment — pre-existing, unrelated).Not this PR
series_info.ingest_locations— rejected in localSeriesManifestPath cannot fetch a remote manifest — series reads fail on cloud-only downloads DID-matlab#201 for the same reason; would defeat the manifest-as-address-book design and inflate documents linearly with member count.Related
SyncFiles=falseround-trip test and audit theupdateFileInfoForLocalFilescloud-reference workaround once this lands.🤖 Generated with Claude Code
https://claude.ai/code/session_015dKpDXCo8VTS4AHiibNnCp
Generated by Claude Code