-
Notifications
You must be signed in to change notification settings - Fork 859
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance Enhancement :Enable Passing of requestPath to CRT and monitor the progress using CRTs S3MetaRequestProgress #4379
Conversation
63065aa
to
6c97310
Compare
…r Progress Updates for putObject Operations
6c97310
to
0e28441
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Is it possible to test that what we're intending to fix actually got fixed?
- Is there performance testing to verify that this change didn't hurt performance?
- Do we already have tests that assert the progress listener changes were backwards compatible?
- Are there any path-processing nuances that may have changed when we switched to the CRT? E.g. handling of the current working directory or expansion of ~/?
progressUpdater.registerCompletion(returnFuture); | ||
|
||
try { | ||
assertNotUnsupportedArn(putObjectRequest.bucket(), "upload"); | ||
|
||
CompletableFuture<PutObjectResponse> crtFuture = | ||
s3AsyncClient.putObject(putObjectRequest, requestBody); | ||
s3AsyncClient.putObject(putObjectRequest, AsyncRequestBody.fromFile(uploadFileRequest.source())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If CRT is reading directly from disk, does this publisher get used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CRT directly gets this from file. The Publisher here is in the S3Client Interface and a non null is required just to get the content length a I have updated the code to throw an exception if we try to read the Java SDKs Publisher in such cases.
/** | ||
* S3CrtProgressListener delegates events to the underlying delegateListener if defined, avoiding null checks for API when using | ||
* S3MetaRequestProgress for GET calls. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like a weird application of polymorphism. Instead of S3CrtProgressListener, can we just have a NoOpPublisherListener that we create if delegateListener is null? That just means we need the null check in the setup code of S3CrtResponseHandlerAdapter instead of per-method here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created NoOpPublisherListener
public static final S3InternalSdkHttpExecutionAttribute<Path> SOURCE_REQ_PATH = | ||
new S3InternalSdkHttpExecutionAttribute<>(Path.class); | ||
|
||
|
||
public static final S3InternalSdkHttpExecutionAttribute<PublisherListener> CRT_PROGRESS_LISTENER = | ||
new S3InternalSdkHttpExecutionAttribute<>(PublisherListener.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is marked as @SdkInternalApi, so it can't be used by the transfer manager module, like we're doing above. Do we need to move a subset to a @SdkProtectedApi?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
public static final S3InternalSdkHttpExecutionAttribute<Path> SOURCE_REQ_PATH = | ||
new S3InternalSdkHttpExecutionAttribute<>(Path.class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming nitpicks, since this actually seems like a protected API.
SOURCE
- Do we ever expect to use this for something other than a PutObject - like a GetObject, where it's actually theDESTINATION
?REQ
- We should almost always use the full word for something instead of shortening it, soREQUEST
. It looks like a lot of the existing properties are request properties, though, so I don't think REQUEST is necessary.
If it's always the source, what about PUT_OBJECT_PATH
? UPLOAD_PATH
?
If it's potentially also destination, what about UPLOAD_DOWNLOAD_PATH
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Matt..
Named it as OBJECT_FILE_PATH so that it can be used for any file path for get/put
58fabbd
to
e047e6c
Compare
Thanks Matt for this suggestion , tested this and realized the CRT doesnot actually fix the issue where upload file size is more than RAM size. I have cut a different ticket to CRT. However , this fix is still needed for performance enhancement. Removed the mention of the orginal issue.
Yes , I saw that the latencies was reduced to half , I have updated the internal doc.
Yes , we already have test .
No. |
.../main/java/software/amazon/awssdk/transfer/s3/internal/progress/TransferProgressUpdater.java
Outdated
Show resolved
Hide resolved
...-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/CrtS3TransferManager.java
Outdated
Show resolved
Hide resolved
.../src/it/java/software/amazon/awssdk/services/s3/crt/S3CrtClientPutObjectIntegrationTest.java
Outdated
Show resolved
Hide resolved
...a/software/amazon/awssdk/services/s3/internal/crt/S3TmInternalSdkHttpExecutionAttribute.java
Outdated
Show resolved
Hide resolved
...a/software/amazon/awssdk/services/s3/internal/crt/S3TmInternalSdkHttpExecutionAttribute.java
Outdated
Show resolved
Hide resolved
@@ -46,9 +48,14 @@ public final class S3CrtResponseHandlerAdapter implements S3MetaRequestResponseH | |||
private final SdkHttpResponse.Builder respBuilder = SdkHttpResponse.builder(); | |||
private volatile S3MetaRequest metaRequest; | |||
|
|||
public S3CrtResponseHandlerAdapter(CompletableFuture<Void> executeFuture, SdkAsyncHttpResponseHandler responseHandler) { | |||
private final PublisherListener<S3MetaRequestProgress> progressListener; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to invoke this.progressListener.subscriberOnError();
in onErrorResponseComplete
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are already calling this.progressListener.subscriberOnError(exception);
from failResponseHandlerAndFuture
which is called from errorPayload != null
also errorPayload == null
for valid errorPayloads
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
failResponseHandlerAndFuture
doesn't seem to be invoked from onErrorResponseComplete
if it successfully marshalls the error response though. Can we add a test to verify it? This test may not suffice now that we are relying on the real CRT client to report progress and it is using a mock s3 client.
responsePublisher.send(ByteBuffer.wrap(errorPayload))
.thenRun(responsePublisher::complete)
.handle((ignore, throwable) -> {
if (throwable != null) {
failResponseHandlerAndFuture(throwable);
return null;
}
completeFutureAndCloseRequest();
return null;
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added new mock tests and removed explicit onError
...oftware/amazon/awssdk/services/s3/internal/crt/CrtContentLengthOnlyAsyncFileRequestBody.java
Show resolved
Hide resolved
e047e6c
to
6af3397
Compare
@@ -107,8 +107,7 @@ public void publisherSubscribe(Subscriber<? super S3MetaRequestProgress> subscri | |||
|
|||
@Override | |||
public void subscriberOnNext(S3MetaRequestProgress s3MetaRequestProgress) { | |||
incrementBytesTransferred(Math.toIntExact(s3MetaRequestProgress.getBytesTransferred()), | |||
s3MetaRequestProgress.getContentLength()); | |||
incrementBytesTransferred(Math.toIntExact(s3MetaRequestProgress.getBytesTransferred())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably should not cast it to int. Can we change incrementBytesTransferred to take a long instead?
...oftware/amazon/awssdk/services/s3/internal/crt/CrtContentLengthOnlyAsyncFileRequestBody.java
Show resolved
Hide resolved
@@ -46,9 +48,14 @@ public final class S3CrtResponseHandlerAdapter implements S3MetaRequestResponseH | |||
private final SdkHttpResponse.Builder respBuilder = SdkHttpResponse.builder(); | |||
private volatile S3MetaRequest metaRequest; | |||
|
|||
public S3CrtResponseHandlerAdapter(CompletableFuture<Void> executeFuture, SdkAsyncHttpResponseHandler responseHandler) { | |||
private final PublisherListener<S3MetaRequestProgress> progressListener; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
failResponseHandlerAndFuture
doesn't seem to be invoked from onErrorResponseComplete
if it successfully marshalls the error response though. Can we add a test to verify it? This test may not suffice now that we are relying on the real CRT client to report progress and it is using a mock s3 client.
responsePublisher.send(ByteBuffer.wrap(errorPayload))
.thenRun(responsePublisher::complete)
.handle((ignore, throwable) -> {
if (throwable != null) {
failResponseHandlerAndFuture(throwable);
return null;
}
completeFutureAndCloseRequest();
return null;
});
0791331
to
65ddbca
Compare
9247f21
to
137862e
Compare
8df43eb
to
1cac2de
Compare
1cac2de
to
aaa43a0
Compare
5d6b70e
to
152d896
Compare
SonarCloud Quality Gate failed. 0 Bugs 55.9% Coverage Catch issues before they fail your Quality Gate with our IDE extension SonarLint |
Motivation and Context
Modifications
Testing
Screenshots (if appropriate)
Types of changes
License