Real per-chunk upload progress (web + native, 0.6.11)#43
Merged
Conversation
Per-chunk cumulative upload progress for the put_flat (web) path via put_object_chunked_internal. Resumable (native) path + FRB bindings to follow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… 0.6.11 Apps can now show a true upload percentage instead of a time-based estimate, on web + native (iOS/Android/Windows). The SDK emits cumulative bytes as each content chunk's PUT lands; Flutter surfaces it via a pollable handle. SDK (fula-client, encryption.rs): - put_object_flat_with_progress — web/chunked path. - put_object_encrypted_resumable_with_cancel_and_progress — native fresh. - resume_upload_with_cancel_and_progress — native resume; SEEDS the counter with already-uploaded chunks so the bar continues mid-way and still reaches 100% though only the remaining chunks are re-PUT. The existing public _with_cancel / resume_upload_with_cancel keep their signatures (external test callers depend on them) and are now thin wrappers delegating with progress=None. Emit is count-proportional, fired from inside each spawned chunk task via a shared AtomicU64. No change to the upload or crypto data path — only added emit calls + new wrapper methods. FRB (fula-flutter, forest.rs): - Polling transport, NOT StreamSink: ProgressHandle (opaque, mirrors CancelHandle) + create_progress_handle + poll_progress(-> UploadProgress). StreamSink stream-handler codegen has never been exercised through the external publish pipeline and can't be verified locally; polling is the proven pattern (MasterHealthEvent, CancelHandle). - put_flat_with_progress (web+native); put_flat_resumable_from_path_with_progress + resume_flat_upload_from_path_with_progress (native; take &CancelHandle + &ProgressHandle). Apps poll poll_progress on a timer during the upload. Tests: - resumable_put_progress.rs — native fresh (max==total) + resume seed-correctness (max==total reachable only when seeded; partial manifest produced by a real failed attempt, not hand-built). - upload_progress_real_server_e2e.rs — live-master E2E, both paths, 3 MiB multi-chunk, progress reaches 100% + byte-identical round-trip (verified: 12 events, max == file size on both paths). - chunk_put_progress.rs (web) from the prior wip commit. - Full fula-client --features test-fault-injection suite green (208 lib + all integration; F1 nonce-reuse ordering + resumable_forest_persistence + v2 bridge tests unperturbed by the wrapper refactor). cargo check green: fula-flutter native (Send+Sync gate), fula-client wasm32, fula-flutter wasm32. Workspace version 0.6.10 -> 0.6.11. Consumer note (FxFiles): SDK reports content 0 -> total; cumulative hits total when the last chunk's PUT returns, before the index PUT + forest-flush tail — UIs should cap at <100% until their own completion signal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Real per-chunk upload progress so apps can show a true percentage instead of a time-based estimate — on web + native (iOS/Android/Windows). Workspace
0.6.10 → 0.6.11.SDK (
fula-client)The chunked upload paths now emit cumulative bytes the moment each content chunk's PUT lands (count-proportional:
completed_chunks · total / N):put_object_flat_with_progress.put_object_encrypted_resumable_with_cancel_and_progress.resume_upload_with_cancel_and_progress— seeds the counter with the already-uploaded chunk count, so the bar continues mid-way and still reaches 100% even though only the remaining chunks are re-PUT.The existing public
put_object_encrypted_resumable_with_cancel/resume_upload_with_cancelkeep their signatures (external test callers depend on them) — they're now thin wrappers delegating to the*_and_progressbodies withprogress = None. Progress is anOption<Arc<dyn Fn(u64,u64)+Send+Sync>>; emitted from inside the spawned chunk tasks via a sharedAtomicU64so it reflects real concurrent completion order. No change to the upload/crypto data path — only added emit calls + new wrapper methods.Flutter bridge (
fula-flutter)Progress is surfaced by polling an opaque handle, mirroring the proven
CancelHandle/MasterHealthEventpattern — notStreamSink(stream-handler codegen has never been exercised through the external publish pipeline; can't verify locally):ProgressHandle+create_progress_handle()+poll_progress() -> UploadProgress.put_flat_with_progress(web + native),put_flat_resumable_from_path_with_progress+resume_flat_upload_from_path_with_progress(native, take&CancelHandle+&ProgressHandle).Apps poll
poll_progresson a timer while the upload future runs. The handle'sArclifecycle is the cleanup (no global registry, no leak on early-return/panic).Tests
chunk_put_progress.rs— web path reaches 100% (max == total).resumable_put_progress.rs— native fresh (max == total) + resume seed-correctness (max == totalis reachable only when the counter is seeded; the partial manifest is produced by a real failed attempt, not hand-built — F1 BAO rejects synthetic manifests).upload_progress_real_server_e2e.rs— live-master E2E for both paths (3 MiB multi-chunk, asserts progress reaches 100% + byte-identical round-trip).fula-client --features test-fault-injectionsuite green (F1 nonce-reuse ordering, resumable_forest_persistence, v2 bridge tests unperturbed by the refactor).Compile gates
cargo checkgreen: fula-flutter native (theSend+Syncgate for the callback across the 16 spawned chunk tasks), fula-client wasm32, fula-flutter wasm32.Consumer note (FxFiles)
SDK reports content
0 → total; cumulative hitstotalwhen the last chunk's PUT returns, before the index PUT + forest-flush tail — UIs should cap at <100% until their own completion signal (reuse the mobile clamp).🤖 Generated with Claude Code