Repository navigation
Rebuild series ingest_locations on SyncFiles=false download (#302) - #303
Merged
stevevanhooser merged 2 commits intoSep 14, 2026
Merged
Conversation
updateFileInfoForRemoteFiles now teaches series to survive a SyncFiles=false cloud round trip. DID strips ingest_locations before storing a document, so one that comes back declares n_present members with no location for any of them -- exactly the shape DID's MembersNotLocatable guard (DID-matlab#185) refuses on add_docs. The whole SyncFiles=false path was blocked on that guard for any document carrying a populated series. The manifest bytes are not on disk on this path -- SyncFiles=false does not download them -- so the reconstruction has to fetch. It goes through the DID custom_file_handler contract (VH-Lab/DID-matlab#201, VH-Lab/DID-python#88), the same contract DID uses on the read side, so a caller with a handler already can pass it in and both sides use the same one. With no handler, fetch_cloud_file is called directly, matching what the read-side handler does when a manifest is asked for by uid. Manifests fetched here do NOT land in the DID file cache; a subsequent member open trips DID#201's lazy fetch, which is what populates the cache. Cache eviction on a later session is answered by the same re-fetch path. A per-manifest fetch failure leaves the entry un-reconstructed so DID's guard fires on add_docs with the document's own identity -- the right signal a partial download deserves. Ported from VH-Lab/NDI-matlab#988. Offline coverage in tests/test_cloud_series_reconstruction_remote.py exercises the same mock-handler pattern NDI-matlab uses in TestUpdateFileInfoForRemoteFilesShape (VH-Lab/NDI-matlab#987): walk a doc through DID's store/read cycle so ingest_locations gets stripped, reshape via updateFileInfoForRemoteFiles with a mock, and pin the rebuilt shape. Two-argument custom_file_handlers still work through the same arity-aware dispatch DID-python uses on its side (_dispatch_custom_file_handler mirrors DID's private helper of the same shape). Also acknowledges an unrelated GUI-side drift: VH-Lab/NDI-matlab#984 raises the open GEF Manager for a session instead of building a second one -- App Designer window uniqueness only, nothing to port this side. Hash bumped on the porting_deferred GEFManager entry. Refs: VH-Lab/NDI-matlab#986, VH-Lab/NDI-matlab#987, VH-Lab/NDI-matlab#988, VH-Lab/DID-matlab#185, VH-Lab/DID-matlab#201, VH-Lab/DID-python#88. Closes #302. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdGZ8fRPeY9JSpUHgXm9ao
Fixes the lint job on PR #303. No behavioural change. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdGZ8fRPeY9JSpUHgXm9ao
stevevanhooser
deleted the
claude/rebuild-ingest-locations-syncfiles-false
branch
September 14, 2026 23:08
This was referenced Sep 14, 2026
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.
Closes #302. Ports VH-Lab/NDI-matlab#988 -- the SyncFiles=false half of the file-series cloud round trip.
What changes
ndi.cloud.filehandler.updateFileInfoForRemoteFilesnow teaches series to survive a SyncFiles=false cloud round trip. DID stripsingest_locationsbefore storing a document, so one that comes back declaresn_presentmembers with no location for any of them -- exactly the shape DID'sMembersNotLocatableguard (DID-matlab#185 / DID-python's_reject_series_without_ingest_locations) refuses onadd_docs. The whole SyncFiles=false path was blocked on that guard for any document carrying a populated series.The manifest bytes are not on disk on this path -- SyncFiles=false does not download them -- so the reconstruction has to fetch. It goes through the DID
custom_file_handlercontract (VH-Lab/DID-matlab#201, VH-Lab/DID-python#88), the same contract DID uses on the read side, so a caller with a handler already can pass it in and both sides use the same one. With no handler,fetch_cloud_fileis called directly, matching what the read-side handler does when a manifest is asked for by uid.Manifests fetched here do not land in the DID file cache; a subsequent member open trips DID#201's lazy fetch, which is what populates the cache. Cache eviction on a later session is answered by the same re-fetch path.
Code
src/ndi/cloud/filehandler.py:updateFileInfoForRemoteFilesgains keyword-onlycustom_file_handler=Noneandclient=None. After the file_info rewrite it checks_needs_series_reconstruction; when a series hasn_present > 0and emptyingest_locations,_reconstruct_series_from_cloudfetches each qualifying manifest to a scratchtempfile.TemporaryDirectoryand callsreconstructSeriesIngestLocationsbefore the temp dir is cleaned up._fetch_manifestdispatches through the handler when given (withseriesName=""in the context -- a non-empty seriesName marks a MEMBER fetch, where the handler treatsctx.uidas the file to retrieve andsource_pathas the manifest, the exact opposite of what we want here) or falls back tofetch_cloud_file._dispatch_custom_file_handlermirrors DID-python's arity-aware dispatch, so a two-argument handler still works.add_docswith the document's own identity.Bridge yaml:
updateFileInfoForRemoteFiles'smatlab_last_sync_hashbumped toaea0c72c(the NDI-matlab main head that carries #988).custom_file_handlerandclientrecorded as keyword-only arguments.Tests
tests/test_cloud_series_reconstruction_remote.py(new, seven tests, all offline):TestFileInfoReshape-- every file_info location becomesndicloud,ingest=0,delete_original=0, uid survives, location isndic://<dataset>/<uid>. Covers both plain and series documents.TestReconstructionSkipsWhenNotNeeded-- a doc whoseingest_locationsis already populated skips reconstruction (no fetch, no handler call). Same for a doc withoutseries_info.TestReconstructionThroughAMockHandler-- end-to-end offline: a mock handler serves manifest bytes by uid; the test walks a doc through DID'sdatabase_add/database_searchcycle soingest_locationsgets stripped (the exact shape a cloud round trip returns), reshapes viaupdateFileInfoForRemoteFiles(..., custom_file_handler=mock), and pins:ndic://location,ingest=0.seriesName=""in the handler context on the manifest fetch.ingest_locationsempty so DID's guard fires on add.Mirrors NDI-matlab's
tests/+ndi/+unittest/+database/TestUpdateFileInfoForRemoteFilesShape.m(VH-Lab/NDI-matlab#987) shape-for-shape.Verification
74 passed, 2 skipped. Bridge checks (
test_matlab_bridge_hashes.py,test_matlab_bridge_completeness.py) all green with the local NDI-matlab checkout.Unrelated GUI drift acknowledged
GEFManager'smatlab_last_sync_hashbumped from06f31a4e5to59c96e57(VH-Lab/NDI-matlab#984 -- raise the open GEF Manager for a session instead of building a second one). MATLAB App Designer window uniqueness only, nothing to port on this side; hash bumped with a decision_log note so the drift check no longer trips on any PR opened after that commit landed.Not in scope
A Python analog of NDI-matlab's
FileSeriesRoundTripTest.testMembersSurviveADownloadFromTheCloudWithSyncFilesFalse-- the live-cloud round-trip test. Belongs in its own change, layered after this one; flagged in the closing note on #300 and to be filed as its own issue.References
🤖 Generated with Claude Code
https://claude.ai/code/session_01AdGZ8fRPeY9JSpUHgXm9ao
Generated by Claude Code