/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ package software.amazon.awssdk.crt.s3; import java.util.concurrent.CompletableFuture; import software.amazon.awssdk.crt.CrtResource; public class S3MetaRequest extends CrtResource { private final CompletableFuture shutdownComplete = new CompletableFuture<>(); public S3MetaRequest() { } private void onShutdownComplete() { releaseReferences(); this.shutdownComplete.complete(null); } /** * Determines whether a resource releases its dependencies at the same time the * native handle is released or if it waits. Resources that wait are responsible * for calling releaseReferences() manually. */ @Override protected boolean canReleaseReferencesImmediately() { return false; } /** * Cleans up the native resources associated with this client. The client is * unusable after this call */ @Override protected void releaseNativeHandle() { if (!isNull()) { s3MetaRequestDestroy(getNativeHandle()); } } void setMetaRequestNativeHandle(long nativeHandle) { acquireNativeHandle(nativeHandle); } public CompletableFuture getShutdownCompleteFuture() { return shutdownComplete; } public void cancel() { if (isNull()) { throw new IllegalStateException("S3MetaRequest has been closed."); } s3MetaRequestCancel(getNativeHandle()); } /** * Pauses meta request and returns a token that can be used to resume a meta request. * For PutObject resume, input stream should always start at the beginning, * already uploaded parts will be skipped, but checksums on those will be verified if request specified checksum algo. * @return token to resume request. might be null if request has not started executing yet */ public ResumeToken pause() { if (isNull()) { throw new IllegalStateException("S3MetaRequest has been closed."); } return s3MetaRequestPause(getNativeHandle()); } /** * Increment the flow-control window, so that response data continues downloading. *

* If the client was created with {@link S3ClientOptions#withReadBackpressureEnabled} set true, * each S3MetaRequest has a flow-control window that shrinks as response * body data is downloaded (headers do not affect the size of the window). * {@link S3ClientOptions#withInitialReadWindowSize} sets the starting size for each S3MetaRequest's window. * Whenever the window reaches zero, data stops downloading. * Increment the window to keep data flowing. * Maintain a larger window to keep up a high download throughput, * parts cannot download in parallel unless the window is large enough to hold multiple parts. * Maintain a smaller window to limit the amount of data buffered in memory. *

* If backpressure is disabled this call has no effect, data is downloaded as fast as possible. *

* WARNING: This feature is experimental. * Currently, backpressure is only applied to GetObject requests which are split into multiple parts, * and you may still receive some data after the window reaches zero. * * @param bytes size to increment window by * @see S3ClientOptions#withReadBackpressureEnabled */ public void incrementReadWindow(long bytes) { if (isNull()) { throw new IllegalStateException("S3MetaRequest has been closed."); } s3MetaRequestIncrementReadWindow(getNativeHandle(), bytes); } /******************************************************************************* * native methods ******************************************************************************/ private static native void s3MetaRequestDestroy(long s3MetaRequest); private static native void s3MetaRequestCancel(long s3MetaRequest); private static native ResumeToken s3MetaRequestPause(long s3MetaRequest); private static native void s3MetaRequestIncrementReadWindow(long s3MetaRequest, long bytes); }