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

Add NettyByteBuf to GetBlobOperation #1314

Merged
merged 6 commits into from
Jan 31, 2020

Conversation

justinlin-linkedin
Copy link
Collaborator

This starts to use Netty ByteBuf in GetBlobOperation.

This PR seeks the least intrusive way to introduce Netty ByteBuf to GetBlobOperation, so it ignores a lot of places where the ByteBuffer can be replaced by Netty ByteBuf.

The major change is to change the buffer/inputstream in BlobData to use Netty ByteBuf.

@codecov-io
Copy link

codecov-io commented Nov 21, 2019

Codecov Report

Merging #1314 into master will decrease coverage by 0.03%.
The diff coverage is 70.73%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master    #1314      +/-   ##
============================================
- Coverage     72.04%   72.01%   -0.04%     
- Complexity     6699     6714      +15     
============================================
  Files           486      486              
  Lines         38163    38207      +44     
  Branches       4843     4843              
============================================
+ Hits          27495    27513      +18     
- Misses         9352     9382      +30     
+ Partials       1316     1312       -4
Impacted Files Coverage Δ Complexity Δ
...ava/com.github.ambry/store/HardDeleteVerifier.java 0% <0%> (ø) 0 <0> (ø) ⬇️
.../com.github.ambry/tools/admin/ServerAdminTool.java 0% <0%> (ø) 0 <0> (ø) ⬇️
...github.ambry/tools/perf/ServerReadPerformance.java 0% <0%> (ø) 0 <0> (ø) ⬇️
...va/com.github.ambry/tools/admin/BlobValidator.java 0% <0%> (ø) 0 <0> (ø) ⬇️
...hub.ambry.messageformat/ValidatingTransformer.java 90% <100%> (-0.25%) 5 <0> (ø)
...in/java/com.github.ambry/network/ResponseInfo.java 90% <100%> (+3.63%) 10 <0> (-1) ⬇️
...om.github.ambry.replication/BlobIdTransformer.java 95.08% <100%> (ø) 22 <0> (ø) ⬇️
.../com.github.ambry.utils/ByteBufferInputStream.java 94.73% <100%> (+3.24%) 18 <0> (-1) ⬇️
.../main/java/com.github.ambry.router/DecryptJob.java 94.59% <100%> (+0.3%) 6 <0> (+1) ⬆️
...ithub.ambry.messageformat/MessageFormatRecord.java 82.17% <100%> (ø) 29 <4> (+1) ⬆️
... and 14 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4e2b8dd...81fb3a6. Read the comment docs.

Copy link
Contributor

@jsjtzyy jsjtzyy left a comment

Choose a reason for hiding this comment

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

Mostly looks good. A few comments.

@@ -1197,18 +1190,15 @@ void handleBody(ResponseInfo responseInfo, InputStream payload, MessageMetadata
}
}
blobType = blobData.getBlobType();
chunkIndexToBuffer = new TreeMap<>();
chunkIndexToResponseInfo = new ConcurrentHashMap<>();
chunkIndexToBuf = new ConcurrentHashMap<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be ConcurrentHashMap?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We will remove ByteBuf from this hash map in other threads, so at least it has to be thread safe.

ByteBuffer chunkBuffer = blobData.getStream().getByteBuffer();
responseInfo.retain();
chunkIndexToResponseInfo.put(chunkIndex, responseInfo);
ByteBuf chunkBuffer = blobData.getAndRelease();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: let's call it chunkBuf

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated.

@@ -838,7 +836,7 @@ void handleResponse(ResponseInfo responseInfo, GetResponse getResponse) {
* @param targetBlobId the {@link BlobId} of the blob.
* @return {@code true} if a crypto job was launched, otherwise {@code false}.
*/
protected boolean maybeLaunchCryptoJob(ByteBuffer dataBuffer, byte[] userMetadata, ByteBuffer encryptionKey,
protected boolean maybeLaunchCryptoJob(ByteBuf dataBuffer, byte[] userMetadata, ByteBuffer encryptionKey,
Copy link
Contributor

Choose a reason for hiding this comment

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

How about making variable naming consistent, if its type is ByteBuf, we call it **Buf?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated

@@ -857,7 +855,7 @@ protected boolean maybeLaunchCryptoJob(ByteBuffer dataBuffer, byte[] userMetadat
decryptCallbackResultInfo = new DecryptCallBackResultInfo();
progressTracker.initializeCryptoJobTracker(CryptoJobType.DECRYPTION);
decryptJobMetricsTracker.onJobSubmission();
cryptoJobHandler.submitJob(new DecryptJob(targetBlobId, encryptionKey, dataBuffer,
cryptoJobHandler.submitJob(new DecryptJob(targetBlobId, encryptionKey, dataBuffer.retainedDuplicate(),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see the dataBuffer is released in this method. (Correct me if I misunderstood)

Copy link
Collaborator Author

@justinlin-linkedin justinlin-linkedin Nov 25, 2019

Choose a reason for hiding this comment

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

dataBuffer is not created in this function, so we don't release it here. But it will be released in the DecryptJob.

return stream;
}

/**
* Return the netty {@link ByteBuf} and then transfer the ownship to the caller. It's not safe
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: ownership. And why it's not safe to call this more than once? You have byteBuf == null check here. Caller is supposed to check result.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since this is not an reentrant method, calling this method multiple time would get you multiple result so it's better not to call it twice.

Copy link
Contributor

Choose a reason for hiding this comment

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

ownship -> ownership

return null;
}
ByteBuffer temp = ByteBuffer.allocate(byteBuf.readableBytes());
byteBuf.writeBytes(temp);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why writeBytes here? I feel like it's supposed to be readBytes from byteBuf to temp, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you are right, updated.

}
output.flip();
return output;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like this method can be replaced by ByteBufferInputStream and call getByteBuffer() to obtain the byteBuffer. At least we can consider reusing the code in the ctor of ByteBufferInputStream.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated

@justinlin-linkedin justinlin-linkedin force-pushed the getopnetty branch 2 times, most recently from 06f5bc5 to 3d31576 Compare November 25, 2019 23:35
/**
* Decrease the reference count of underlying response.
*/
public void release() {
if (response != null) {
ReferenceCountUtil.release(response);
response = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this only be set to null when the refcount reaches zero?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

now that we remove the retain function, we can be sure that we only need to release it once.

Copy link
Contributor

@cgtz cgtz left a comment

Choose a reason for hiding this comment

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

I can merge after these comments are addressed

return stream;
}

/**
* Return the netty {@link ByteBuf} and then transfer the ownship to the caller. It's not safe
Copy link
Contributor

Choose a reason for hiding this comment

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

ownship -> ownership

@@ -73,14 +74,18 @@ public void run() {
Object containerKey = kms.getKey(blobId.getAccountId(), blobId.getContainerId());
Object perBlobKey = cryptoService.decryptKey(encryptedPerBlobKey, containerKey);
if (encryptedBlobContent != null) {
decryptedBlobContent = cryptoService.decrypt(encryptedBlobContent, perBlobKey);
decryptedBlobContent = cryptoService.decrypt(encryptedBlobContent.nioBuffer(), perBlobKey);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not use the CryptoService.decrypt(ByteBuf, Key) method here? I think the default method has some special handling for edge cases with composite buffers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

planning on call the other method in a different PR, where I will change bytebuffer in DecryptJob and EncryptJob to ByteBuf.

build.gradle Show resolved Hide resolved
@cgtz cgtz merged commit 3cdb994 into linkedin:master Jan 31, 2020
@justinlin-linkedin justinlin-linkedin deleted the getopnetty branch January 31, 2020 17:35
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.

4 participants