You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by bb...@apache.org on 2023/05/04 18:27:18 UTC
[hbase] branch branch-2 updated: HBASE-27799: RpcThrottlingException wait interval message is misleading between 0-1s (#5192)
This is an automated email from the ASF dual-hosted git repository.
bbeaudreault pushed a commit to branch branch-2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2 by this push:
new 0b7252bcfa4 HBASE-27799: RpcThrottlingException wait interval message is misleading between 0-1s (#5192)
0b7252bcfa4 is described below
commit 0b7252bcfa4cb2450f8ca728ac9380e7b89d192f
Author: Ray Mattingly <rm...@gmail.com>
AuthorDate: Thu May 4 14:12:11 2023 -0400
HBASE-27799: RpcThrottlingException wait interval message is misleading between 0-1s (#5192)
Signed-off-by: Bryan Beaudreault <bb...@apache.org>
---
.../hbase/quotas/RpcThrottlingException.java | 59 +++++++++++++-----
.../hbase/quotas/TestRpcThrottlingException.java | 72 ++++++++++++++++++++++
2 files changed, 114 insertions(+), 17 deletions(-)
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/RpcThrottlingException.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/RpcThrottlingException.java
index 1cb8abf490d..2c1f13e94e6 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/RpcThrottlingException.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/quotas/RpcThrottlingException.java
@@ -20,7 +20,6 @@ package org.apache.hadoop.hbase.quotas;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.hbase.HBaseIOException;
-import org.apache.hadoop.util.StringUtils;
import org.apache.yetus.audience.InterfaceAudience;
/**
@@ -130,29 +129,55 @@ public class RpcThrottlingException extends HBaseIOException {
private static void throwThrottlingException(final Type type, final long waitInterval)
throws RpcThrottlingException {
- String msg = MSG_TYPE[type.ordinal()] + MSG_WAIT + StringUtils.formatTime(waitInterval);
+ String msg = MSG_TYPE[type.ordinal()] + MSG_WAIT + stringFromMillis(waitInterval);
throw new RpcThrottlingException(type, waitInterval, msg);
}
- private static long timeFromString(String timeDiff) {
- Pattern[] patterns = new Pattern[] { Pattern.compile("^(\\d+\\.\\d\\d)sec"),
- Pattern.compile("^(\\d+)mins, (\\d+\\.\\d\\d)sec"),
- Pattern.compile("^(\\d+)hrs, (\\d+)mins, (\\d+\\.\\d\\d)sec") };
+ // Visible for TestRpcThrottlingException
+ protected static String stringFromMillis(long millis) {
+ StringBuilder buf = new StringBuilder();
+ long hours = millis / (60 * 60 * 1000);
+ long rem = (millis % (60 * 60 * 1000));
+ long minutes = rem / (60 * 1000);
+ rem = rem % (60 * 1000);
+ long seconds = rem / 1000;
+ long milliseconds = rem % 1000;
- for (int i = 0; i < patterns.length; ++i) {
- Matcher m = patterns[i].matcher(timeDiff);
- if (m.find()) {
- long time = Math.round(Float.parseFloat(m.group(1 + i)) * 1000);
- if (i > 0) {
- time += Long.parseLong(m.group(i)) * (60 * 1000);
- }
- if (i > 1) {
- time += Long.parseLong(m.group(i - 1)) * (60 * 60 * 1000);
+ if (hours != 0) {
+ buf.append(hours);
+ buf.append(hours > 1 ? "hrs, " : "hr, ");
+ }
+ if (minutes != 0) {
+ buf.append(minutes);
+ buf.append(minutes > 1 ? "mins, " : "min, ");
+ }
+ if (seconds != 0) {
+ buf.append(seconds);
+ buf.append("sec, ");
+ }
+ buf.append(milliseconds);
+ buf.append("ms");
+ return buf.toString();
+ }
+
+ // Visible for TestRpcThrottlingException
+ protected static long timeFromString(String timeDiff) {
+ Pattern pattern =
+ Pattern.compile("^(?:(\\d+)hrs?, )?(?:(\\d+)mins?, )?(?:(\\d+)sec[, ]{0,2})?(?:(\\d+)ms)?");
+ long[] factors = new long[] { 60 * 60 * 1000, 60 * 1000, 1000, 1 };
+ Matcher m = pattern.matcher(timeDiff);
+ if (m.find()) {
+ int numGroups = m.groupCount();
+ long time = 0;
+ for (int j = 1; j <= numGroups; j++) {
+ String group = m.group(j);
+ if (group == null) {
+ continue;
}
- return time;
+ time += Math.round(Float.parseFloat(group) * factors[j - 1]);
}
+ return time;
}
-
return -1;
}
}
diff --git a/hbase-client/src/test/java/org/apache/hadoop/hbase/quotas/TestRpcThrottlingException.java b/hbase-client/src/test/java/org/apache/hadoop/hbase/quotas/TestRpcThrottlingException.java
new file mode 100644
index 00000000000..21b01ad4764
--- /dev/null
+++ b/hbase-client/src/test/java/org/apache/hadoop/hbase/quotas/TestRpcThrottlingException.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.quotas;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Map;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableMap;
+
+@Category({ SmallTests.class })
+public class TestRpcThrottlingException {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestRpcThrottlingException.class);
+
+ private static final Map<String, Long> STR_TO_MS_NEW_FORMAT =
+ ImmutableMap.<String, Long> builder().put("0ms", 0L).put("50ms", 50L).put("1sec, 1ms", 1001L)
+ .put("1min, 5sec, 15ms", 65_015L).put("5mins, 2sec, 0ms", 302000L)
+ .put("1hr, 3mins, 5sec, 1ms", 3785001L).put("1hr, 5sec, 1ms", 3605001L)
+ .put("1hr, 0ms", 3600000L).put("1hr, 1min, 1ms", 3660001L).build();
+ private static final Map<String,
+ Long> STR_TO_MS_LEGACY_FORMAT = ImmutableMap.<String, Long> builder().put("0sec", 0L)
+ .put("1sec", 1000L).put("2sec", 2000L).put("1mins, 5sec", 65_000L).put("5mins, 2sec", 302000L)
+ .put("1hrs, 3mins, 5sec", 3785000L).build();
+
+ @Test
+ public void itConvertsMillisToNewString() {
+ for (Map.Entry<String, Long> strAndMs : STR_TO_MS_NEW_FORMAT.entrySet()) {
+ String output = RpcThrottlingException.stringFromMillis(strAndMs.getValue());
+ assertEquals(strAndMs.getKey(), output);
+ }
+ }
+
+ @Test
+ public void itConvertsNewStringToMillis() {
+ for (Map.Entry<String, Long> strAndMs : STR_TO_MS_NEW_FORMAT.entrySet()) {
+ Long output = RpcThrottlingException.timeFromString(strAndMs.getKey());
+ assertEquals(strAndMs.getValue(), output);
+ }
+ }
+
+ @Test
+ public void itConvertsLegacyStringToMillis() {
+ for (Map.Entry<String, Long> strAndMs : STR_TO_MS_LEGACY_FORMAT.entrySet()) {
+ Long output = RpcThrottlingException.timeFromString(strAndMs.getKey());
+ assertEquals(strAndMs.getValue(), output);
+ }
+ }
+
+}