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) { processing = false; }
138 }
139
140 public synchronized int size() {
141 return deadServers.size();
142 }
143
144 public synchronized boolean isEmpty() {
145 return deadServers.isEmpty();
146 }
147
148 public synchronized void cleanAllPreviousInstances(final ServerName newServerName) {
149 Iterator<ServerName> it = deadServers.keySet().iterator();
150 while (it.hasNext()) {
151 ServerName sn = it.next();
152 if (ServerName.isSameHostnameAndPort(sn, newServerName)) {
153 it.remove();
154 }
155 }
156 }
157
158 public synchronized String toString() {
159 StringBuilder sb = new StringBuilder();
160 for (ServerName sn : deadServers.keySet()) {
161 if (sb.length() > 0) {
162 sb.append(", ");
163 }
164 sb.append(sn.toString());
165 }
166 return sb.toString();
167 }
168
169
170
171
172
173
174 public synchronized List<Pair<ServerName, Long>> copyDeadServersSince(long ts){
175 List<Pair<ServerName, Long>> res = new ArrayList<Pair<ServerName, Long>>(size());
176
177 for (Map.Entry<ServerName, Long> entry:deadServers.entrySet()){
178 if (entry.getValue() >= ts){
179 res.add(new Pair<ServerName, Long>(entry.getKey(), entry.getValue()));
180 }
181 }
182
183 Collections.sort(res, ServerNameDeathDateComparator);
184 return res;
185 }
186
187
188
189
190
191
192 public synchronized Date getTimeOfDeath(final ServerName deadServerName){
193 Long time = deadServers.get(deadServerName);
194 return time == null ? null : new Date(time);
195 }
196
197 private static Comparator<Pair<ServerName, Long>> ServerNameDeathDateComparator =
198 new Comparator<Pair<ServerName, Long>>(){
199
200 @Override
201 public int compare(Pair<ServerName, Long> o1, Pair<ServerName, Long> o2) {
202 return o1.getSecond().compareTo(o2.getSecond());
203 }
204 };
205 }