001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.quotas; 019 020import java.util.regex.Matcher; 021import java.util.regex.Pattern; 022import org.apache.yetus.audience.InterfaceAudience; 023 024/** 025 * Describe the throttling result. TODO: At some point this will be handled on the client side to 026 * prevent operation to go on the server if the waitInterval is grater than the one got as result of 027 * this exception. 028 * @deprecated replaced by {@link RpcThrottlingException} since hbase-2.0.0. 029 */ 030@Deprecated 031@InterfaceAudience.Public 032public class ThrottlingException extends QuotaExceededException { 033 private static final long serialVersionUID = 1406576492085155743L; 034 035 @InterfaceAudience.Public 036 public enum Type { 037 NumRequestsExceeded, 038 RequestSizeExceeded, 039 NumReadRequestsExceeded, 040 NumWriteRequestsExceeded, 041 WriteSizeExceeded, 042 ReadSizeExceeded, 043 } 044 045 private static final String[] MSG_TYPE = new String[] { "number of requests exceeded", 046 "request size limit exceeded", "number of read requests exceeded", 047 "number of write requests exceeded", "write size limit exceeded", "read size limit exceeded", }; 048 049 private static final String MSG_WAIT = " - wait "; 050 051 private long waitInterval; 052 private Type type; 053 054 public ThrottlingException(String msg) { 055 super(msg); 056 057 // Dirty workaround to get the information after 058 // ((RemoteException)e.getCause()).unwrapRemoteException() 059 for (int i = 0; i < MSG_TYPE.length; ++i) { 060 int index = msg.indexOf(MSG_TYPE[i]); 061 if (index >= 0) { 062 String waitTimeStr = msg.substring(index + MSG_TYPE[i].length() + MSG_WAIT.length()); 063 type = Type.values()[i]; 064 waitInterval = timeFromString(waitTimeStr); 065 break; 066 } 067 } 068 } 069 070 public ThrottlingException(final Type type, final long waitInterval, final String msg) { 071 super(msg); 072 this.waitInterval = waitInterval; 073 this.type = type; 074 } 075 076 public Type getType() { 077 return this.type; 078 } 079 080 public long getWaitInterval() { 081 return this.waitInterval; 082 } 083 084 public static void throwNumRequestsExceeded(final long waitInterval) throws ThrottlingException { 085 throwThrottlingException(Type.NumRequestsExceeded, waitInterval); 086 } 087 088 public static void throwRequestSizeExceeded(final long waitInterval) throws ThrottlingException { 089 throwThrottlingException(Type.RequestSizeExceeded, waitInterval); 090 } 091 092 public static void throwNumReadRequestsExceeded(final long waitInterval) 093 throws ThrottlingException { 094 throwThrottlingException(Type.NumReadRequestsExceeded, waitInterval); 095 } 096 097 public static void throwNumWriteRequestsExceeded(final long waitInterval) 098 throws ThrottlingException { 099 throwThrottlingException(Type.NumWriteRequestsExceeded, waitInterval); 100 } 101 102 public static void throwWriteSizeExceeded(final long waitInterval) throws ThrottlingException { 103 throwThrottlingException(Type.WriteSizeExceeded, waitInterval); 104 } 105 106 public static void throwReadSizeExceeded(final long waitInterval) throws ThrottlingException { 107 throwThrottlingException(Type.ReadSizeExceeded, waitInterval); 108 } 109 110 private static void throwThrottlingException(final Type type, final long waitInterval) 111 throws ThrottlingException { 112 String msg = MSG_TYPE[type.ordinal()] + MSG_WAIT + formatTime(waitInterval); 113 throw new ThrottlingException(type, waitInterval, msg); 114 } 115 116 public static String formatTime(long timeDiff) { 117 StringBuilder buf = new StringBuilder(); 118 long hours = timeDiff / (60 * 60 * 1000); 119 long rem = (timeDiff % (60 * 60 * 1000)); 120 long minutes = rem / (60 * 1000); 121 rem = rem % (60 * 1000); 122 float seconds = rem / 1000.0f; 123 124 if (hours != 0) { 125 buf.append(hours); 126 buf.append("hrs, "); 127 } 128 if (minutes != 0) { 129 buf.append(minutes); 130 buf.append("mins, "); 131 } 132 buf.append(String.format("%.2fsec", seconds)); 133 return buf.toString(); 134 } 135 136 private static long timeFromString(String timeDiff) { 137 Pattern[] patterns = new Pattern[] { Pattern.compile("^(\\d+\\.\\d\\d)sec"), 138 Pattern.compile("^(\\d+)mins, (\\d+\\.\\d\\d)sec"), 139 Pattern.compile("^(\\d+)hrs, (\\d+)mins, (\\d+\\.\\d\\d)sec") }; 140 141 for (int i = 0; i < patterns.length; ++i) { 142 Matcher m = patterns[i].matcher(timeDiff); 143 if (m.find()) { 144 long time = Math.round(Float.parseFloat(m.group(1 + i)) * 1000); 145 if (i > 0) { 146 time += Long.parseLong(m.group(i)) * (60 * 1000); 147 } 148 if (i > 1) { 149 time += Long.parseLong(m.group(i - 1)) * (60 * 60 * 1000); 150 } 151 return time; 152 } 153 } 154 155 return -1; 156 } 157}