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 @InterfaceAudience.Private
43 public class DeadServer {
44 private static final Log LOG = LogFactory.getLog(DeadServer.class);
45
46
47
48
49
50
51
52
53 private final Map<ServerName, Long> deadServers = new HashMap<ServerName, Long>();
54
55
56
57
58 private int numProcessing = 0;
59
60
61
62
63
64
65
66
67
68 public synchronized boolean cleanPreviousInstance(final ServerName newServerName) {
69 Iterator<ServerName> it = deadServers.keySet().iterator();
70 while (it.hasNext()) {
71 ServerName sn = it.next();
72 if (ServerName.isSameHostnameAndPort(sn, newServerName)) {
73 it.remove();
74 return true;
75 }
76 }
77
78 return false;
79 }
80
81
82
83
84
85 public synchronized boolean isDeadServer(final ServerName serverName) {
86 return deadServers.containsKey(serverName);
87 }
88
89
90
91
92
93
94
95
96 public synchronized boolean areDeadServersInProgress() {
97 return numProcessing != 0;
98 }
99
100 public synchronized Set<ServerName> copyServerNames() {
101 Set<ServerName> clone = new HashSet<ServerName>(deadServers.size());
102 clone.addAll(deadServers.keySet());
103 return clone;
104 }
105
106
107
108
109
110 public synchronized void add(ServerName sn) {
111 this.numProcessing++;
112 if (!deadServers.containsKey(sn)){
113 deadServers.put(sn, EnvironmentEdgeManager.currentTime());
114 }
115 }
116
117 public synchronized void finish(ServerName sn) {
118 LOG.debug("Finished processing " + sn);
119 this.numProcessing--;
120 }
121
122 public synchronized int size() {
123 return deadServers.size();
124 }
125
126 public synchronized boolean isEmpty() {
127 return deadServers.isEmpty();
128 }
129
130 public synchronized void cleanAllPreviousInstances(final ServerName newServerName) {
131 Iterator<ServerName> it = deadServers.keySet().iterator();
132 while (it.hasNext()) {
133 ServerName sn = it.next();
134 if (ServerName.isSameHostnameAndPort(sn, newServerName)) {
135 it.remove();
136 }
137 }
138 }
139
140 public synchronized String toString() {
141 StringBuilder sb = new StringBuilder();
142 for (ServerName sn : deadServers.keySet()) {
143 if (sb.length() > 0) {
144 sb.append(", ");
145 }
146 sb.append(sn.toString());
147 }
148 return sb.toString();
149 }
150
151
152
153
154
155
156 public synchronized List<Pair<ServerName, Long>> copyDeadServersSince(long ts){
157 List<Pair<ServerName, Long>> res = new ArrayList<Pair<ServerName, Long>>(size());
158
159 for (Map.Entry<ServerName, Long> entry:deadServers.entrySet()){
160 if (entry.getValue() >= ts){
161 res.add(new Pair<ServerName, Long>(entry.getKey(), entry.getValue()));
162 }
163 }
164
165 Collections.sort(res, ServerNameDeathDateComparator);
166 return res;
167 }
168
169
170
171
172
173
174 public synchronized Date getTimeOfDeath(final ServerName deadServerName){
175 Long time = deadServers.get(deadServerName);
176 return time == null ? null : new Date(time);
177 }
178
179 private static Comparator<Pair<ServerName, Long>> ServerNameDeathDateComparator =
180 new Comparator<Pair<ServerName, Long>>(){
181
182 @Override
183 public int compare(Pair<ServerName, Long> o1, Pair<ServerName, Long> o2) {
184 return o1.getSecond().compareTo(o2.getSecond());
185 }
186 };
187 }