Skip to content

feat: async chunk upload, dynamic part sizing for multi-TB uploads, and RUFH compliance improvements - #138

Open
tomdesair wants to merge 6 commits into
masterfrom
feature/async-chunk-upload
Open

tomdesair wants to merge 6 commits into
masterfrom
feature/async-chunk-upload

Conversation

@tomdesair

Copy link
Copy Markdown
Owner

Summary of Changes

This pull request introduces asynchronous chunk uploading for cloud storage backends, adds dynamic part sizing to reliably support multi-TB uploads (up to 5 TB), and incorporates compliance improvements for both Tus v1.0.0 and IETF Resumable Uploads for HTTP (RUFH).

1. Asynchronous Chunk Upload Pipeline

  • Introduced AsyncChunkUploader managing bounded in-flight cloud part uploads concurrently via uploadExecutor.
  • Stream payload processing buffers disk chunks up to preferred part size and hands them off asynchronously to the upload queue.
  • In-flight futures are tracked and drained gracefully (drainAndComplete()), ensuring sequential block/part tracking while maximizing network throughput.

2. Multi-TB Upload Support & Dynamic Part Sizing

  • Implemented calcOptimalPartSize(expectedLength) across storage services.
  • If announced upload size requires larger parts to stay strictly within S3/Azure's 10,000-part ceiling (e.g. for uploads above 50 GB and up to 5 TB), part sizes automatically scale (e.g. up to 500 MB per part).
  • Configurable preferredPartSize / preferredBlockSize with fluent builders on TusFileUploadService.

3. Exemption of Completing Uploads from Min-Append-Size (§4.1.4)

  • Enforced RUFH §4.1.4 exemption across S3 and Azure Blob storage: uploads completing via Upload-Complete: ?1 or requests reaching full length bypass the min-append-size constraint.
  • Updated RufhCreationPostRequestHandler and RufhAppendPatchRequestHandler to resolve announced length from Content-Length on completing uploads per §4.2.1.
  • Added comprehensive unit and integration tests across S3StorageServiceTest, ITAzureBlobStorageService, RufhCreationPostRequestHandlerTest, RufhAppendPatchRequestHandlerTest, and AbstractITRufhProtocol.

4. Interim Response Endpoint Isolation

  • Updated RufhInterimResponseUtil to verify that the request target corresponds to the service's configured creation endpoint via Utils.isCreationEndpoint().
  • Prevents interim response valves from interfering across multi-backend setups (e.g. Disk, S3, Azure demo endpoints).

5. Tus v1.0.0 & RUFH Conformity Test Suites

  • Added scripts/tus_conformity_test.py covering Tus v1.0.0 specification requirements.
  • Updated docs/CONFORMITY_TESTING.md and README.md to document default test execution across all three storage backends (Disk, S3, Azure).
  • Fixed HTTP 460 Checksum Mismatch handling in TusFileUploadService to prevent Spring Boot error controller degradation to 500.
  • Enhanced Azure server-side block copying with read SAS tokens for private containers.

@coveralls

coveralls commented Sep 28, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 94.42% (-0.5%) from 94.902% — feature/async-chunk-upload into master

- Skip redundant isLockExpired pre-check in S3LockingService for optimistic conditional PutObject
- Batch delete .lock and .stop keys via S3 Multi-Object Delete in S3UploadLock
- Clean up unused deleteS3LockObjectIfOwner and deleteS3ObjectQuietly methods
- Remove createMinioContainer alias from TestUtils and clarify RustFS Testcontainers setup
- Update CHANGELOG.md
… streamlined constructors

- Added configurable jitter bounds (withJitter) in AbstractLeaseLockingService and S3LockingService defaulting to 20-60 ms, with zero-jitter support (0, 0) for pure AWS S3 / Cloudflare R2 deployments.
- Implemented automatic non-CAS fallback in S3LockingService when If-None-Match: * returns HTTP 501 / NotImplemented (supporting Backblaze B2, Ceph RGW) along with withS3ConditionalWritesSupported(boolean) override.
- Streamlined S3LockingService constructors to minimal required set (basic 2-arg and full 6-arg).
- Clarified locking documentation and inline comments regarding lock arbitration on non-CAS backends.
- Add withLockWaitTimeout(Duration) and getLockWaitTimeout() to TusFileUploadService (default 60s)
- Derive max lock retries (timeout / 200ms, default 300) and cloud upload chunk drain timeout (timeout - 5s, default 55s)
- Update AsyncChunkUploader, UploadStorageService, S3StorageService, AzureBlobStorageService, DiskStorageService, and ThreadLocalCachedStorageAndLockingService to configure and propagate drain timeout
- Update documentation in README.md, CHANGELOG.md, docs/LOCKING.md, docs/S3_STORAGE.md, and docs/AZURE_BLOB_STORAGE.md with lock wait terminology
- Add unit tests for timeout derivation, validation, storage synchronization, and cache delegation
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.

2 participants