Skip to content

feat. Async pause - #1008

Open
TingDaoK wants to merge 9 commits into
mainfrom
async-pause
Open

feat. Async pause#1008
TingDaoK wants to merge 9 commits into
mainfrom
async-pause

Conversation

@TingDaoK

@TingDaoK TingDaoK commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Java bindings for the aws-c-s3 async pause API

Binds the async pause and resume-token APIs from aws-c-s3#649. The existing pause() is upload-only; this adds an async variant that covers uploads and downloads, plus a callback that hands back a resume token when a transfer fails unexpectedly.

New API

S3MetaRequest.pauseAsync()

public CompletableFuture<ResumeToken> pauseAsync();

Works for both PUT_OBJECT and GET_OBJECT. The future completes only after in-flight work settles (in-flight parts for uploads, file writes for downloads), so the token reflects a quiesced state. Completes with null when the request had not progressed far enough to produce resumable state, or exceptionally with CrtRuntimeException if the pause itself failed.

S3MetaRequestResponseHandler.onErrorResumeToken(int errorCode, ResumeToken resumeToken)

New default method, invoked exactly once when a meta request fails unexpectedly, so callers can persist state and resume without re-transferring completed parts. Supported for uploads and downloads. Not invoked on success or explicit pause. The token is null when no resumable state was captured.

Worth calling out: for a file download with withResponseFileDeleteOnFailure(true), the deletion is respected — the partial file is deleted and the callback fires with a null token. Don't set that option if you intend to resume from this token.

ResumeToken — download fields

Previously upload-only. Nine download getters added: getEtag(), getVersionId(), getS3ObjectLastModified() (HTTP-date string), getObjectSize() (full object size regardless of Range), getObjectRangeStart(), getObjectRangeEnd() (inclusive), getContinuesDownloadedBytes() (contiguous prefix), getTotalDownloadedBytes(), getFileLastModifiedEpochNs().

Type-specific getters throw IllegalArgumentException when read from the wrong token type, matching existing getUploadId() behavior. Use getType() to disambiguate.

Known limitation

Consuming a download token to resume a GET isn't supported yet. Workaround: issue a new ranged GET from getContinuesDownloadedBytes() (offset from getObjectRangeStart()) through getObjectRangeEnd(). Upload resume is unchanged via withResumeToken().

Testing

  • testS3PutPauseAsyncResume — 128MB MPU, pauses via pauseAsync().get(), asserts token fields and cross-type getter rejection, then resumes to completion.
  • testS3GetPauseAsync — 10MB download with read backpressure so the transfer deterministically stalls before the pause, asserts all download token fields.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@TingDaoK
TingDaoK marked this pull request as ready for review July 29, 2026 21:47
@TingDaoK TingDaoK changed the title Async pause feat. Async pause Jul 29, 2026
*
* @return contiguously downloaded bytes
*/
public long getContinuesDownloadedBytes() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: i left a similar comment on c side and thought it was fixes, but looks like continues is a typo here and you meant contiguous

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, I fixed the place you point out in C. but looks like I forgot another one...

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