d-c-manning commented on code in PR #6789:
URL: https://github.com/apache/hbase/pull/6789#discussion_r2032157400
##########
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java:
##########
@@ -8458,16 +8452,24 @@ public void startRegionOperation(Operation op) throws
IOException {
coprocessorHost.postStartRegionOperation(op);
}
} catch (Exception e) {
- if (isInterruptableOp) {
- // would be harmless to remove what we didn't add but we know by
'isInterruptableOp'
- // if we added this thread to regionLockHolders
- regionLockHolders.remove(thisThread);
- }
+ lockHolders.remove(thisThread);
lock.readLock().unlock();
throw new IOException(e);
}
}
+ private static boolean shouldLock(Operation op) {
+ // split, merge or compact region doesn't need to check the closing/closed
state or lock the
+ // region
+ List<Operation> lockFreeOperations = Arrays.asList(Operation.MERGE_REGION,
Review Comment:
If we're going to keep this refactor, then we don't need to create a new
List every time we call this method. This could be kept somewhere as a static
list/set. (Maybe compiler already optimizes this, I don't know.)
##########
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java:
##########
@@ -8458,16 +8452,24 @@ public void startRegionOperation(Operation op) throws
IOException {
coprocessorHost.postStartRegionOperation(op);
}
} catch (Exception e) {
- if (isInterruptableOp) {
- // would be harmless to remove what we didn't add but we know by
'isInterruptableOp'
- // if we added this thread to regionLockHolders
- regionLockHolders.remove(thisThread);
- }
+ lockHolders.remove(thisThread);
lock.readLock().unlock();
throw new IOException(e);
}
}
+ private static boolean shouldLock(Operation op) {
+ // split, merge or compact region doesn't need to check the closing/closed
state or lock the
+ // region
+ List<Operation> lockFreeOperations = Arrays.asList(Operation.MERGE_REGION,
+ Operation.SPLIT_REGION, Operation.COMPACT_REGION,
Operation.COMPACT_SWITCH);
+ if (lockFreeOperations.contains(op)) {
+
+ return false;
+ }
+ return true;
Review Comment:
```suggestion
return !lockFreeOperations.contains(op);
```
##########
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java:
##########
@@ -8408,42 +8423,21 @@ public void startRegionOperation() throws IOException {
@Override
public void startRegionOperation(Operation op) throws IOException {
- boolean isInterruptableOp = false;
- switch (op) {
- case GET: // interruptible read operations
- case SCAN:
- isInterruptableOp = true;
- checkReadsEnabled();
- break;
- case INCREMENT: // interruptible write operations
- case APPEND:
- case PUT:
- case DELETE:
- case BATCH_MUTATE:
- case CHECK_AND_MUTATE:
- isInterruptableOp = true;
- break;
- default: // all others
- break;
- }
- if (
- op == Operation.MERGE_REGION || op == Operation.SPLIT_REGION || op ==
Operation.COMPACT_REGION
- || op == Operation.COMPACT_SWITCH
- ) {
- // split, merge or compact region doesn't need to check the
closing/closed state or lock the
- // region
- return;
- }
+ boolean isInterruptibleOp = isOperationInterruptible(op);
Review Comment:
I think it's weird for a method called `isOperationInterruptible` to throw
an exception. I guess one can inspect the method and follow the logic, but it
still smells weird. I would probably factor the exception throwing code into a
new method `checkOperationAllowed()` or something similar, and call it
separately before calling `isOperationInterruptible`.
(Or alternatively revert to the original format - the method was 60 lines
which isn't extremely long relatively speaking... though I like your general
move towards smaller methods and less cognitive load in reading those methods.)
##########
hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java:
##########
@@ -715,7 +715,8 @@ void sawNoSuchFamily() {
// Used to track interruptible holders of the region lock. Currently that is
only RPC handler
// threads. Boolean value in map determines if lock holder can be
interrupted, normally true,
// but may be false when thread is transiting a critical section.
- final ConcurrentHashMap<Thread, Boolean> regionLockHolders;
+ final ConcurrentHashMap<Thread, Boolean> intrRegionLockHolders;
Review Comment:
I agree with @virajjasani that we probably don't need two maps here, and we
do seem to be losing some readability advantages.
Two options:
1. `isOperationInterruptible` is effectively static based on the op... so
inside of `enableInterrupts` or `disableInterrupts` methods, we can also only
take action `if isOperationInterruptible`.
2. If we think that somehow an op could be interruptible, perhaps in the
future, based on dynamic properties of the op... then we could create a class
(or pair) to track two booleans - one for whether to interrupt, and one for
whether to ever interrupt. Then, similar to (1) above, we can use that other
boolean to determine whether to `enableInterrupts` or `disableInterrupts`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]