Skip to content

fula-client 0.6.14: wasm/web cancellable chunked upload (mirror native cancel)#46

Merged
ehsan6sha merged 1 commit into
mainfrom
feat/wasm-upload-cancel
Jun 18, 2026
Merged

fula-client 0.6.14: wasm/web cancellable chunked upload (mirror native cancel)#46
ehsan6sha merged 1 commit into
mainfrom
feat/wasm-upload-cancel

Conversation

@ehsan6sha

Copy link
Copy Markdown
Member

Summary

Adds cooperative cancel to the wasm/web (non-resumable) chunked-upload path, mirroring the SDK's existing native resumable cancel. This lets the web Sync Queue abort an in-progress large upload (Stage 2 of the web upload-cancel/resume plan; resumable is 0.6.15).

Changes

  • put_object_chunked_internal + the shared put_object_flat_deferred_locked take an optional cancel: Option<Arc<AtomicBool>> (the 3 existing callers pass None — unchanged).
  • The per-chunk buffer_unordered closure checks the flag before the chunk PUT: a not-yet-started chunk short-circuits with ClientError::Cancelled; chunks already in flight (≤16) finish. A second check before the index PUT covers cancel-after-all-chunks. The existing post-loop compensating-delete removes the uploaded (now-unreferenced) chunks — same cleanup as the failure path.
  • New pub put_object_flat_with_progress_cancellable(... progress, cancel).
  • FRB put_flat_with_progress_cancellable(&ProgressHandle, &CancelHandle) shares the CancelHandle's Arc<AtomicBool> with the upload.
  • Workspace version → 0.6.14.

Validation

  • Compiles clean: fula-client native + wasm32, fula-flutter native.
  • Unit test: a pre-set cancel flag aborts the chunked upload with Cancelled.
  • Regression: progress + native-resumable progress tests pass.
  • Reviewed: built-in advisor (implementation-level concurrency analysis) — sound. External concurrency reviewers (Gemini + Qwen-coder) in flight; codex quota-limited until July.

NON-resumable

A cancelled upload restarts from scratch. wasm resumable (IndexedDB manifest, BAO integrity) is the next change (0.6.15).

Dart wiring (post-publish, not in this PR)

When wiring the web Sync Queue against 0.6.14:

  1. Cancelled must bypass retryAsync/isTransientUploadError and not be re-enqueued by _pump (else a cancelled upload re-runs).
  2. Cancelled must surface as a distinguishable "cancelled", not a generic failure toast.
  3. The real gate is a live mid-flight web E2E (cancel partway → stops + cleans orphaned chunks + queue advances).

🤖 Generated with Claude Code

…e cancel)

The web (non-resumable) chunked-upload path had no cancel — only the native
resumable path could abort an in-flight upload (an Arc<AtomicBool> checked
between chunk PUTs). This adds the SAME cooperative cancel to the wasm-capable
non-resumable path so the web Sync Queue can stop an in-progress large upload.

- `put_object_chunked_internal` + the shared `put_object_flat_deferred_locked`
  take an optional `cancel: Option<Arc<AtomicBool>>` (the 3 existing callers
  pass None — unchanged). The per-chunk `buffer_unordered` closure checks it
  before the chunk PUT: a chunk not yet started short-circuits with
  `ClientError::Cancelled`; chunks already in flight (<=16) finish. A second
  check before the index PUT covers cancel-after-all-chunks. The existing
  post-loop compensating-delete removes the uploaded (now-unreferenced) chunks
  — the same cleanup as the failure path. Mirrors the native resumable cancel.
- New `pub put_object_flat_with_progress_cancellable(... progress, cancel)`.
- FRB binding `put_flat_with_progress_cancellable(&ProgressHandle, &CancelHandle)`
  shares the CancelHandle's `Arc<AtomicBool>` with the upload, so triggering the
  Dart-held handle sets the flag the upload polls.

NON-resumable: a cancelled upload restarts from scratch — wasm RESUMABLE
support is the next change (0.6.15). Compiles on native + wasm32 + flutter; a
unit test asserts a pre-set cancel flag aborts with `Cancelled`; the progress
and native-resumable regression tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ehsan6sha ehsan6sha merged commit 1d9b0f7 into main Jun 18, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant