feat: support out-of-order chunked uploads in Local adapter#162
feat: support out-of-order chunked uploads in Local adapter#162TorstenDittmann merged 9 commits intomainfrom
Conversation
- Remove fragile _chunks.log file and use .part.{n} files as single source of truth
- Fix duplicate chunk detection in uploadData() to match upload()
- Write part files before counting to avoid count/desync issues
- Add countChunks() helper using glob() for reliable chunk counting
- Add out-of-order upload tests for Local and S3 adapters
- Add .gitignore to disk-a test resources to ignore test artifacts
Greptile SummaryThis PR replaces the
Confidence Score: 3/5Not safe to merge as-is: a race condition in the duplicate-chunk path can trigger double assembly and corrupt the output file under concurrent load. One P1 finding (double joinChunks() race via unconditional countChunks() after duplicate detection) pulls the score below the P1 ceiling of 4. The rest of the changes are clean and well-tested. src/Storage/Device/Local.php — both upload() and uploadData() need an early return in the duplicate branch before countChunks() is called. Important Files Changed
|
Summary
This PR enables out-of-order chunked uploads for the Local storage adapter by replacing the fragile
_chunks.logfile with.part.{n}files as the single source of truth.Problem
The Local adapter previously tracked uploaded chunks via a
_chunks.logfile. This had several issues:uploadData()— re-uploading a chunk would append duplicate log entries, inflating the count and potentially deadlocking the upload.upload()— the log entry was written before the part file was moved. If the move failed, the log and disk were out of sync.Solution
Local Adapter (
src/Storage/Device/Local.php)_chunks.logentirely.countChunks()helper that usesglob()to count existing.part.{n}files in the temp directory.upload()anduploadData()to:$chunks..part.{n}file already exists.joinChunks()to no longer attempt to delete the (now non-existent) log file.Tests
testOutOfOrderUpload— uploads chunks 3→1→2 and verifies correct assembly.testOutOfOrderUploadWithRetry— uploads 2→1→retry 2→3, verifying duplicates are ignored.testJoinChunksMissingPartDoesNotFinalize— updated to reflect the safer new behavior (missing parts simply prevent finalization instead of throwing during assembly).testOutOfOrderPartUpload(S3) — uploads all chunks of a large file in reverse order to verify S3 natively supports out-of-order multipart uploads.Misc
.gitignoretotests/resources/disk-a/to prevent test artifacts from being tracked.Testing
All upload-related tests pass:
The remaining failures in the full suite (
testTransferLarge,testTransferSmall,testGetFiles) are pre-existing environment issues (missing AWS credentials / macOS permissions) and are unrelated to these changes.