1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.client;
21
22 import java.io.IOException;
23 import java.net.ConnectException;
24 import java.net.SocketTimeoutException;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.HRegionInfo;
30 import org.apache.hadoop.hbase.HRegionLocation;
31 import org.apache.hadoop.hbase.NotServingRegionException;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.exceptions.RegionMovedException;
34 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ClientService;
35 import org.apache.hadoop.hbase.util.Bytes;
36
37
38
39
40
41
42
43
44
45
46
47 @InterfaceAudience.Private
48 public abstract class RegionServerCallable<T> implements RetryingCallable<T> {
49
50 static final Log LOG = LogFactory.getLog(RegionServerCallable.class);
51 protected final Connection connection;
52 protected final TableName tableName;
53 protected final byte[] row;
54 protected HRegionLocation location;
55 private ClientService.BlockingInterface stub;
56
57 protected final static int MIN_WAIT_DEAD_SERVER = 10000;
58
59
60
61
62
63
64 public RegionServerCallable(Connection connection, TableName tableName, byte [] row) {
65 this.connection = connection;
66 this.tableName = tableName;
67 this.row = row;
68 }
69
70
71
72
73
74
75
76 @Override
77 public void prepare(final boolean reload) throws IOException {
78 try (RegionLocator regionLocator = connection.getRegionLocator(tableName)) {
79 this.location = regionLocator.getRegionLocation(row, reload);
80 }
81 if (this.location == null) {
82 throw new IOException("Failed to find location, tableName=" + tableName +
83 ", row=" + Bytes.toString(row) + ", reload=" + reload);
84 }
85 setStub(getConnection().getClient(this.location.getServerName()));
86 }
87
88
89
90
91 HConnection getConnection() {
92 return (HConnection) this.connection;
93 }
94
95 protected ClientService.BlockingInterface getStub() {
96 return this.stub;
97 }
98
99 void setStub(final ClientService.BlockingInterface stub) {
100 this.stub = stub;
101 }
102
103 protected HRegionLocation getLocation() {
104 return this.location;
105 }
106
107 protected void setLocation(final HRegionLocation location) {
108 this.location = location;
109 }
110
111 public TableName getTableName() {
112 return this.tableName;
113 }
114
115 public byte [] getRow() {
116 return this.row;
117 }
118
119 @Override
120 public void throwable(Throwable t, boolean retrying) {
121 if (t instanceof SocketTimeoutException ||
122 t instanceof ConnectException ||
123 t instanceof RetriesExhaustedException ||
124 (location != null && getConnection().isDeadServer(location.getServerName()))) {
125
126
127
128 if (this.location != null) getConnection().clearCaches(location.getServerName());
129 } else if (t instanceof RegionMovedException) {
130 getConnection().updateCachedLocations(tableName, row, t, location);
131 } else if (t instanceof NotServingRegionException && !retrying) {
132
133
134 getConnection().deleteCachedRegionLocation(location);
135 }
136 }
137
138 @Override
139 public String getExceptionMessageAdditionalDetail() {
140 return "row '" + Bytes.toString(row) + "' on table '" + tableName + "' at " + location;
141 }
142
143 @Override
144 public long sleep(long pause, int tries) {
145 long sleep = ConnectionUtils.getPauseTime(pause, tries);
146 if (sleep < MIN_WAIT_DEAD_SERVER
147 && (location == null || getConnection().isDeadServer(location.getServerName()))) {
148 sleep = ConnectionUtils.addJitter(MIN_WAIT_DEAD_SERVER, 0.10f);
149 }
150 return sleep;
151 }
152
153
154
155
156 public HRegionInfo getHRegionInfo() {
157 if (this.location == null) {
158 return null;
159 }
160 return this.location.getRegionInfo();
161 }
162 }