1
2
3
4
5
6
7
8
9
10
11
12 package org.apache.hadoop.hbase.quotas;
13
14 import java.util.regex.Matcher;
15 import java.util.regex.Pattern;
16
17 import org.apache.hadoop.hbase.classification.InterfaceAudience;
18 import org.apache.hadoop.hbase.classification.InterfaceStability;
19
20
21
22
23
24
25
26 @InterfaceAudience.Public
27 @InterfaceStability.Evolving
28 public class ThrottlingException extends QuotaExceededException {
29 private static final long serialVersionUID = 1406576492085155743L;
30
31 @InterfaceAudience.Public
32 @InterfaceStability.Evolving
33 public enum Type {
34 NumRequestsExceeded, RequestSizeExceeded, NumReadRequestsExceeded, NumWriteRequestsExceeded,
35 WriteSizeExceeded, ReadSizeExceeded,
36 }
37
38 private static final String[] MSG_TYPE =
39 new String[] { "number of requests exceeded", "request size limit exceeded",
40 "number of read requests exceeded", "number of write requests exceeded",
41 "write size limit exceeded", "read size limit exceeded", };
42
43 private static final String MSG_WAIT = " - wait ";
44
45 private long waitInterval;
46 private Type type;
47
48 public ThrottlingException(String msg) {
49 super(msg);
50
51
52
53 for (int i = 0; i < MSG_TYPE.length; ++i) {
54 int index = msg.indexOf(MSG_TYPE[i]);
55 if (index >= 0) {
56 String waitTimeStr = msg.substring(index + MSG_TYPE[i].length() + MSG_WAIT.length());
57 type = Type.values()[i];
58 waitInterval = timeFromString(waitTimeStr);
59 break;
60 }
61 }
62 }
63
64 public ThrottlingException(final Type type, final long waitInterval, final String msg) {
65 super(msg);
66 this.waitInterval = waitInterval;
67 this.type = type;
68 }
69
70 public Type getType() {
71 return this.type;
72 }
73
74 public long getWaitInterval() {
75 return this.waitInterval;
76 }
77
78 public static void throwNumRequestsExceeded(final long waitInterval) throws ThrottlingException {
79 throwThrottlingException(Type.NumRequestsExceeded, waitInterval);
80 }
81
82 public static void throwRequestSizeExceeded(final long waitInterval)
83 throws ThrottlingException {
84 throwThrottlingException(Type.RequestSizeExceeded, waitInterval);
85 }
86
87 public static void throwNumReadRequestsExceeded(final long waitInterval)
88 throws ThrottlingException {
89 throwThrottlingException(Type.NumReadRequestsExceeded, waitInterval);
90 }
91
92 public static void throwNumWriteRequestsExceeded(final long waitInterval)
93 throws ThrottlingException {
94 throwThrottlingException(Type.NumWriteRequestsExceeded, waitInterval);
95 }
96
97 public static void throwWriteSizeExceeded(final long waitInterval) throws ThrottlingException {
98 throwThrottlingException(Type.WriteSizeExceeded, waitInterval);
99 }
100
101 public static void throwReadSizeExceeded(final long waitInterval) throws ThrottlingException {
102 throwThrottlingException(Type.ReadSizeExceeded, waitInterval);
103 }
104
105 private static void throwThrottlingException(final Type type, final long waitInterval)
106 throws ThrottlingException {
107 String msg = MSG_TYPE[type.ordinal()] + MSG_WAIT + formatTime(waitInterval);
108 throw new ThrottlingException(type, waitInterval, msg);
109 }
110
111 public static String formatTime(long timeDiff) {
112 StringBuilder buf = new StringBuilder();
113 long hours = timeDiff / (60 * 60 * 1000);
114 long rem = (timeDiff % (60 * 60 * 1000));
115 long minutes = rem / (60 * 1000);
116 rem = rem % (60 * 1000);
117 float seconds = rem / 1000.0f;
118
119 if (hours != 0) {
120 buf.append(hours);
121 buf.append("hrs, ");
122 }
123 if (minutes != 0) {
124 buf.append(minutes);
125 buf.append("mins, ");
126 }
127 buf.append(String.format("%.2fsec", seconds));
128 return buf.toString();
129 }
130
131 private static long timeFromString(String timeDiff) {
132 Pattern[] patterns =
133 new Pattern[] { Pattern.compile("^(\\d+\\.\\d\\d)sec"),
134 Pattern.compile("^(\\d+)mins, (\\d+\\.\\d\\d)sec"),
135 Pattern.compile("^(\\d+)hrs, (\\d+)mins, (\\d+\\.\\d\\d)sec") };
136
137 for (int i = 0; i < patterns.length; ++i) {
138 Matcher m = patterns[i].matcher(timeDiff);
139 if (m.find()) {
140 long time = Math.round(Float.parseFloat(m.group(1 + i)) * 1000);
141 if (i > 0) {
142 time += Long.parseLong(m.group(i)) * (60 * 1000);
143 }
144 if (i > 1) {
145 time += Long.parseLong(m.group(i - 1)) * (60 * 60 * 1000);
146 }
147 return time;
148 }
149 }
150
151 return -1;
152 }
153 }