-
Notifications
You must be signed in to change notification settings - Fork 3.4k
HBASE-24680 Refactor the checkAndMutate code on the server side #2094
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
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@Apache9 Can you please review this when you get a chance? |
joshelser
left a comment
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.
Generally looks OK to me. I don't have a lot of experience in the new CheckAndMutate objects, though.
|
|
||
| try { | ||
| if (mutations.size() == 1) { | ||
| if (mutations.get(0) instanceof Put) { |
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.
nit: Mutation m = mutations.get(0) and then use m for the rest of this block.
| */ | ||
| default CheckAndMutateResult preCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c, | ||
| CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException { | ||
| if (checkAndMutate.getAction() instanceof Put) { |
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.
Every time I see this, I want to suggest you use a visitor pattern to reduce the boilerplate, but that would require putting more logic on Put/Delete which not worth it. 🤷
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.
Put/Delete is public so let's not do this...
| // checkAndMutate tests | ||
| // //////////////////////////////////////////////////////////////////////////// | ||
| @Test | ||
| @Deprecated |
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.
Probably don't need to mark deprecated tests in the future, but this is fine to leave, IMO.
|
@joshelser Thank you very much for reviewing this! I will wait for any other opinions/objections until tomorrow. If nothing, will commit this. |
| * Update checkAndMutate histogram | ||
| * @param t time it took | ||
| */ | ||
| void updateCheckAndMutate(long t); |
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.
After this change, do we still have checkAndPut and checkAndDelete?
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.
Yes. This change keeps the existing metrics for checkAndPut and checkAndDelete for backward compatibility. This change doesn't break the existing tests for the metrics for checkAndPut and checkAndDelete.
| */ | ||
| default CheckAndMutateResult preCheckAndMutate(ObserverContext<RegionCoprocessorEnvironment> c, | ||
| CheckAndMutate checkAndMutate, CheckAndMutateResult result) throws IOException { | ||
| if (checkAndMutate.getAction() instanceof Put) { |
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.
Put/Delete is public so let's not do this...
| throw new DoNotRetryIOException( | ||
| "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); | ||
| } | ||
| } catch (IllegalArgumentException e) { |
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.
Where do we throw this exception out? Catching a RuntimeException seems strange to me.
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.
CheckAndMutate.Builder.build() calls preCheck() internally and it can throw IllegalArgumentException if the parameters are invalid:
hbase/hbase-client/src/main/java/org/apache/hadoop/hbase/client/CheckAndMutate.java
Lines 141 to 151 in 09e7ccd
| private void preCheck(Row action) { | |
| Preconditions.checkNotNull(action, "action (Put/Delete/RowMutations) is null"); | |
| if (!Bytes.equals(row, action.getRow())) { | |
| throw new IllegalArgumentException("The row of the action (Put/Delete/RowMutations) <" + | |
| Bytes.toStringBinary(action.getRow()) + "> doesn't match the original one <" + | |
| Bytes.toStringBinary(this.row) + ">"); | |
| } | |
| Preconditions.checkState(op != null || filter != null, "condition is null. You need to" | |
| + " specify the condition by calling ifNotExists/ifEquals/ifMatches before building a" | |
| + " CheckAndMutate object"); | |
| } |
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.
Then we'd better let the try catch for IllegalArgumentException only wrap the builder.build? And then we call checkAndMutate, without catching the IllegalArgumentException. I think this will be better to let others know why we may hit IllegalArgumentException.
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.
Sure, thanks. Will do that as your review.
| throw new DoNotRetryIOException("Unsupported mutate type: " + | ||
| mutation.getClass().getSimpleName().toUpperCase()); | ||
| } | ||
| } catch (IllegalArgumentException e) { |
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.
Ditto.
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
brfrn169
left a comment
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.
@Apache9 Thank you very much for taking a look at this!
I left some comments for your review. Can you please check them?
| * Update checkAndMutate histogram | ||
| * @param t time it took | ||
| */ | ||
| void updateCheckAndMutate(long t); |
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.
Yes. This change keeps the existing metrics for checkAndPut and checkAndDelete for backward compatibility. This change doesn't break the existing tests for the metrics for checkAndPut and checkAndDelete.
| throw new DoNotRetryIOException( | ||
| "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); | ||
| } | ||
| } catch (IllegalArgumentException e) { |
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.
CheckAndMutate.Builder.build() calls preCheck() internally and it can throw IllegalArgumentException if the parameters are invalid:
hbase/hbase-client/src/main/java/org/apache/hadoop/hbase/client/CheckAndMutate.java
Lines 141 to 151 in 09e7ccd
| private void preCheck(Row action) { | |
| Preconditions.checkNotNull(action, "action (Put/Delete/RowMutations) is null"); | |
| if (!Bytes.equals(row, action.getRow())) { | |
| throw new IllegalArgumentException("The row of the action (Put/Delete/RowMutations) <" + | |
| Bytes.toStringBinary(action.getRow()) + "> doesn't match the original one <" + | |
| Bytes.toStringBinary(this.row) + ">"); | |
| } | |
| Preconditions.checkState(op != null || filter != null, "condition is null. You need to" | |
| + " specify the condition by calling ifNotExists/ifEquals/ifMatches before building a" | |
| + " CheckAndMutate object"); | |
| } |
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
Show resolved
Hide resolved
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Not sure why QA was re-triggered.. The test failure in the last QA is not related to this patch because I ran the failed test locally and it was successful. Kicking QA again. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Looks the QA is okay. Can you please take a look at this? @Apache9 |
|
Ping @Apache9 |
| throw new DoNotRetryIOException( | ||
| "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); | ||
| } | ||
| } catch (IllegalArgumentException e) { |
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.
Then we'd better let the try catch for IllegalArgumentException only wrap the builder.build? And then we call checkAndMutate, without catching the IllegalArgumentException. I think this will be better to let others know why we may hit IllegalArgumentException.
Apache9
left a comment
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.
+1.
Let's wait for the pre commit result.
|
🎊 +1 overall
This message was automatically generated. |
|
🎊 +1 overall
This message was automatically generated. |
|
💔 -1 overall
This message was automatically generated. |
|
I don' think the test failure in the last QA is related to this patch. I ran the failed tests locally and it was successful. Will merge this PR. |
checkAndMutate(CheckAndMutate)toRegion/HRegionand deprecated the old methodscheckAndPut/checkAndDelete/checkAndRowMutatepreCheckAndMutate/preCheckAndMutateAfterRowLock/postCheckAndMutateto RegionObserver and deprecated the old coprocessor methodspreCheckAndPut/preCheckAndPutAfterRowLock/postCheckAndPut/preCheckAndDelete/preCheckAndDeleteAfterRowLock/postCheckAndDeletecheckAndMutate