Skip to content
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

SOLR-16886: Don't commit multi-part uploads that have been aborted #1773

Merged
merged 5 commits into from
Jul 17, 2023

Conversation

tflobbe
Copy link
Member

@tflobbe tflobbe commented Jul 11, 2023

The complete() method is currently being called from the close(), which is called from try-with-resources

@mkhludnev
Copy link
Member

Nice catch. Is there a chance to cover it with some sort of unit test?

@@ -200,6 +202,10 @@ public MultipartUpload(String uploadId) {
}

void uploadPart(ByteArrayInputStream inputStream, long partSize) {
if (aborted) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this could just return like complete() below. Any reason to error here and not there? It'd make the logic a bit simpler in close() as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's true that this isn't consistent with the logic added in close. I kind of like throwing the error instead of just ignoring things because it otherwise hides the fact that the component is being misused (an upload after an abort). The reality is that none of the error paths should happen with the current code. I'm more inclined to throw the ISE exception in the compoete() if aborted than going the other way around.

It'd make the logic a bit simpler in close() as well.

Maybe it's simpler if I check for aborted in close() too and handled separately? let me push a change and see

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah that makes sense to me.

@tflobbe
Copy link
Member Author

tflobbe commented Jul 11, 2023

Nice catch. Is there a chance to cover it with some sort of unit test?

I was trying to see if it was possible with s3mock, but I can't find a way to introduce failures. I could do a Mockito test, or otherwise increase visibility to some methods for testing purposes

Copy link
Contributor

@HoustonPutman HoustonPutman left a comment

Choose a reason for hiding this comment

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

Looks good to me. The mockito tests are clean and test what we need!

@@ -200,6 +202,10 @@ public MultipartUpload(String uploadId) {
}

void uploadPart(ByteArrayInputStream inputStream, long partSize) {
if (aborted) {
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah that makes sense to me.

verify(clientMock).uploadPart((UploadPartRequest) any(), (RequestBody) any());
verify(clientMock, never())
.completeMultipartUpload((Consumer<CompleteMultipartUploadRequest.Builder>) any());
verify(clientMock, times(2))
Copy link
Contributor

Choose a reason for hiding this comment

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

why does it call abort twice?

Copy link
Member Author

Choose a reason for hiding this comment

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

The first time is after calling write for the first time (in line 102 in this test). The S3 client's uploadPart will fail, and after that our S3OutputStream will capture the exception and call abort. The second time is because we call write again in line 109 of this test, in this case, the exception i thrown by our MultipartUpload code (the IllegalStateException) because MPU has already been aborted. This will call abort again. This shouldn't be a problem, since one can call abort on the same ID multiple times (in fact, the javadocs say that one should, to ensure better cleanup of multipart objects, but this isn't really addressing that part)

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the explanation!

@tflobbe tflobbe merged commit 4905213 into apache:main Jul 17, 2023
2 checks passed
@tflobbe tflobbe deleted the abort-multipart branch July 17, 2023 20:29
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.

3 participants