Fix block upload worker leaks after an error - #8
Conversation
Receive every block upload result before returning the first error so all workers can release their semaphore slots. Buffer the result channel and return immediately when slot acquisition fails. Add a regression test which repeats failing batches and then acquires the full semaphore capacity.
a386958 to
1d2e00d
Compare
|
Additional real-world validation from the downstream PDrive integration:
This supports the semaphore-release behavior under repeated real backend failures, beyond the unit and race tests already listed in the PR. A separate bounded retry for only the failed encrypted blocks is tracked in oss-singularity/proton-drive-linux#42 and was validated in oss-singularity/Proton-API-Bridge#2. I am deliberately keeping that follow-up out of this PR so this worker-lifecycle fix remains focused. Once this prerequisite lands, the retry can be proposed upstream as a single independent commit. |
c059d75 to
1d2e00d
Compare
|
Independent confirmation of this bug and fix from a different deployment. We hit the same failure on rclone v1.74.4 syncing ~1.1M files: a We arrived at the same three changes (buffered channel sized to the batch, Related: the block body itself also needs to be replayable for the retry to succeed. The multipart reader is consumed by the first attempt, so a retried block after a connection drop sends an empty body. That half is in rclone/go-proton-api#9. |
|
Thank you, Jose — this is excellent independent confirmation and very useful coverage. I reproduced the regression test from
It adds valuable coverage through the real I also reproduced the two tests from rclone/go-proton-api#9: on Our downstream bridge retry re-enters Thanks again for the careful report and the production evidence. |
|
Thanks for reproducing it so thoroughly. Pushing straight onto an org fork branch is not possible from here, so the test is a one-commit, test-only PR against your branch: oss-singularity#3. It changes no code, just adds the test next to yours. Merge it into the branch or port it with attribution, whichever is easier for you. |
Drive the real uploadAndCollectBlockData path against a local HTTP test server that fails one block of the batch, with blockUploadSemaphore sized to 2, and assert that both permits can be acquired again afterwards. On master (9d772d0) this fails with "context deadline exceeded" because the collector returns on the first error and the remaining worker stays blocked on the unbuffered result channel, never releasing its permit. With the worker-drain change in this PR it passes, including under -race.
|
Done — thank you, Jose. I merged oss-singularity/Proton-API-Bridge#3 via rebase. Your test is now commit The updated head passes the complete Go 1.26 workflow: golangci-lint, This is exactly the additional end-to-end coverage we wanted. Much appreciated. |
Problem
uploadPendingBlocksreturned as soon as it received the first block-upload error. The remaining goroutines could then block while sending to the unbuffered result channel, still holding their weighted-semaphore slots. Repeated retries progressively consumed all block-upload slots and left later uploads unable to start.The acquisition-error path also continued to a deferred
Releaseeven though no slot had been acquired.Fix
uploadAndCollectBlockDatapath against a local HTTP server, fails one block and verifies that every permit is released.The end-to-end test was contributed by Jose Vega in oss-singularity/Proton-API-Bridge#3.
Verification
Validated with Go 1.26 and golangci-lint 2.9.0, matching the repository workflow:
All commands pass. The repository's credential-gated Proton integration tests are skipped by their existing guard; all unit tests, including both regression tests, run successfully.
The fork's repository workflow also passes on the current head: Lint and Test.
Broader coordination
This pull request remains intentionally limited to the block-upload worker leak. Repository-wide backlog triage and OSS Singularity's offer of ongoing stewardship are documented in the rclone forum's existing Proton Drive x rclone discussion.