1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.ServerName;
25 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
26 import org.apache.hadoop.hbase.util.Pair;
27
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38
39
40
41
42
43 @InterfaceAudience.Private
44 public class DeadServer {
45 private static final Log LOG = LogFactory.getLog(DeadServer.class);
46
47
48
49
50
51
52
53
54 private final Map<ServerName, Long> deadServers = new HashMap<ServerName, Long>();
55
56
57
58
59 private int numProcessing = 0;
60
61
62
63
64 private boolean processing = false;
65
66
67
68
69
70
71
72
73
74 public synchronized boolean cleanPreviousInstance(final ServerName newServerName) {
75 Iterator<ServerName> it = deadServers.keySet().iterator();
76 while (it.hasNext()) {
77 ServerName sn = it.next();
78 if (ServerName.isSameHostnameAndPort(sn, newServerName)) {
79 it.remove();
80 return true;
81 }
82 }
83
84 return false;
85 }
86
87
88
89
90
91 public synchronized boolean isDeadServer(final ServerName serverName) {
92 return deadServers.containsKey(serverName);
93 }
94
95
96
97
98
99
100
101
102 public synchronized boolean areDeadServersInProgress() { return processing; }
103
104 public synchronized Set<ServerName> copyServerNames() {
105 Set<ServerName> clone = new HashSet<ServerName>(deadServers.size());
106 clone.addAll(deadServers.keySet());
107 return clone;
108 }
109
110
111
112
113
114 public synchronized void add(ServerName sn) {
115 processing = true;
116 if (!deadServers.containsKey(sn)){
117 deadServers.put(sn, EnvironmentEdgeManager.currentTime());
118 }
119 }
120
121
122
123
124
125 public synchronized void notifyServer(ServerName sn) {
126 if (LOG.isDebugEnabled()) { LOG.debug("Started processing " + sn); }
127 processing = true;
128 numProcessing++;
129 }
130
131 public synchronized void finish(ServerName sn) {
132 numProcessing--;
133 if (LOG.isDebugEnabled()) LOG.debug("Finished " + sn + "; numProcessing=" + numProcessing);
134
135 assert numProcessing >= 0: "Number of dead servers in processing should always be non-negative";
136
137 if (numProcessing < 0) {
138 LOG.error("Number of dead servers in processing = " + numProcessing
139 + ". Something went wrong, this should always be non-negative.");
140 numProcessing = 0;
141 }
142 if (numProcessing == 0) { processing = false; }
143 }
144
145 public synchronized int size() {
146 return deadServers.size();
147 }
148
149 public synchronized boolean isEmpty() {
150 return deadServers.isEmpty();
151 }
152
153 public synchronized void cleanAllPreviousInstances(final ServerName newServerName) {
154 Iterator<ServerName> it = deadServers.keySet().iterator();
155 while (it.hasNext()) {
156 ServerName sn = it.next();
157 if (ServerName.isSameHostnameAndPort(sn, newServerName)) {
158 it.remove();
159 }
160 }
161 }
162
163 public synchronized String toString() {
164 StringBuilder sb = new StringBuilder();
165 for (ServerName sn : deadServers.keySet()) {
166 if (sb.length() > 0) {
167 sb.append(", ");
168 }
169 sb.append(sn.toString());
170 }
171 return sb.toString();
172 }
173
174
175
176
177
178
179 public synchronized List<Pair<ServerName, Long>> copyDeadServersSince(long ts){
180 List<Pair<ServerName, Long>> res = new ArrayList<Pair<ServerName, Long>>(size());
181
182 for (Map.Entry<ServerName, Long> entry:deadServers.entrySet()){
183 if (entry.getValue() >= ts){
184 res.add(new Pair<ServerName, Long>(entry.getKey(), entry.getValue()));
185 }
186 }
187
188 Collections.sort(res, ServerNameDeathDateComparator);
189 return res;
190 }
191
192
193
194
195
196
197 public synchronized Date getTimeOfDeath(final ServerName deadServerName){
198 Long time = deadServers.get(deadServerName);
199 return time == null ? null : new Date(time);
200 }
201
202 private static Comparator<Pair<ServerName, Long>> ServerNameDeathDateComparator =
203 new Comparator<Pair<ServerName, Long>>(){
204
205 @Override
206 public int compare(Pair<ServerName, Long> o1, Pair<ServerName, Long> o2) {
207 return o1.getSecond().compareTo(o2.getSecond());
208 }
209 };
210 }