Repository navigation
feat(locallibrary): stream the files a plugin's net/fetch sends, whole, in parts or in a form - #260
Merged
Merged
Conversation
…ugin's progress ProgressEvent's own `items` (how many items a coalesced `item` stands for) took the `items` of a `phase_start` while it was read, so the start no longer parsed as an event and the host skipped it as unknown: a plugin's phase never began in a front end. It's read by hand now, the count kept only for an `item`.
…e, in parts or in a form A set destination can now upload the set's recording without the host reading it into memory. `body_blob` may name the recording `set/publish` lends the hook (not in its dry run) as well as a scratch file, `body_range` sends part of it, and `multipart` sends a `multipart/form-data` form of text and file parts. The host reads files as it sends them with an exact Content-Length, opens them again for a redirect that resends the body, stops at the next read once cancelled, gives a request sending files 30 s plus the time 128 KiB/s would take, and reports the bytes it sends as the hook's progress in the new `upload` phase.
SizeCompared with main. KiB are 1,024 bytes.
|
Rust coverageFrom run 471. Both are held to the thresholds in .cargo/config.toml.
|
bnb
approved these changes
Oct 26, 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.
What and why
A set destination plugin is handed a set's recording (often 100 MB to 2 GB for a DJ mix) to upload, but
net/fetchcould only send a file from the request's scratch folder, and the host read it into memory first. This lets a plugin send the recording, part of it, or a form with it, while the host reads it from disk as it goes, and shows the upload's progress.Added:
body_range {offset, length?}onnet/fetch(crates/loclib-plugin/src/protocol.rs) sends part of abody_blob, for uploads in parts. A range past the file's end is refused before anything is sent.multipartonnet/fetchsends amultipart/form-dataform:{name, value}text parts (with{secret:}filled in) and{name, file, range?, filename?, content_type?}file parts. The host makes the boundary and theContent-Type.crates/locallibrary/src/plugin/net/body.rsbuilds the body: text, a file or part of one, or a form through reqwest's streaming multipart support (itsmultipartfeature is now on). Files are read as they're sent with an exactContent-Length, opened again when a 307 or 308 resends the body, and sending stops at the next read once the fetch is cancelled. A request that sends files gets 30 s plus the time 128 KiB/s would take, instead of a flat 30 s.Phase::Uploadincrates/loclib-progress, shown as "Uploading" in the CLI and "uploading" in the TUI. The host reports the bytes it sends as that phase's progress, in order with the plugin's ownphase_startandphase_end(Pending::reporter()incrates/loclib-plugin/src/peer.rs).Slot::call_lending(crates/locallibrary/src/plugin/process.rs): publishing a set lends the hook its recording, sonet/fetchmay send it while the hook runs. The dry run lends nothing.Changed:
Scratches(crates/locallibrary/src/plugin/blobs.rs) tracks each hook call under way: its scratch folder, the files lent to it, and where its upload progress goes. A body or form file may be a lent file or one in a scratch folder under way, nothing else.net/fetchignores aContent-Lengththe plugin sets, and for a form, itsContent-Type.ProgressEventis read by hand. Its ownitemscount had been taking aphase_start'sitemswhile it was read, so the host skipped every plugin's phase start as an unknown event and a plugin's phase never showed. This is its own commit.apps/locallibrary/docs/rpc/is regenerated for the new phase.crates/loclib-plugin/README.md,apps/locallibrary/docs/plugins.mdand the CHANGELOG describe the new fields and what a plugin may send.Removed:
net/fetchno longer reads abody_blobinto memory before sending it.The fields are additive and protocol 0.2 hasn't been released, so the version stays. Once it is, a change like this needs a feature flag:
Fetchaccepts unknown fields, so an older host would send a whole file where a plugin asked for a range.How it was tested
crates/locallibrary/tests/it/plugins/net.rs: ranges as a Hegel property over any size, offset and length, plus the edges (offset 0, a last partial part with and without a length, past the end, an empty part at the end); forms as a Hegel property on the exact bytes, boundary andContent-Length; redirects that resend a file (307, 308) or drop it (303); six new refusals in the wrong-request property.crates/locallibrary/tests/it/plugins/destinations.rs: a recording sent in parts while a set is published, with each part's bytes andContent-Lengthand progress going phase start, bytes summing to the file, phase end; refused in the dry run and once publishing is done; a 32 MiB upload to a slow server stopped partway by a cancel.crates/loclib-plugin/src/protocol/tests.rs: a phase start keeps its item count.cargo fmt --check, workspace clippy with-D warnings(andx86_64-pc-windows-gnufor the touched crates), nextest for the touched packages, and coverage over loclib-plugin, locallibrary and loclib-progress (lines 97.39, functions 95.35, regions 94.91).Checklist
apps/locallibrary/CHANGELOG.mdhas a line under Unreleased, if people using it will noticedocs/and--helpstill say what the code does (apps/locallibrary/docs/rpc/too, for a sidecar change)