View Javadoc

1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.master;
21  
22  import java.util.Collection;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.LinkedList;
26  import java.util.List;
27  import java.util.Set;
28  
29  import org.apache.commons.lang.NotImplementedException;
30  import org.apache.hadoop.hbase.HServerInfo;
31  
32  /**
33   * Class to hold dead servers list and utility querying dead server list.
34   */
35  public class DeadServer implements Set<String> {
36    /**
37     * Set of known dead servers.  On znode expiration, servers are added here.
38     * This is needed in case of a network partitioning where the server's lease
39     * expires, but the server is still running. After the network is healed,
40     * and it's server logs are recovered, it will be told to call server startup
41     * because by then, its regions have probably been reassigned.
42     */
43    private final Set<String> deadServers = new HashSet<String>();
44  
45    /** Maximum number of dead servers to keep track of */
46    private final int maxDeadServers;
47  
48    /** Number of dead servers currently being processed */
49    private int numProcessing;
50  
51    public DeadServer(int maxDeadServers) {
52      super();
53      this.maxDeadServers = maxDeadServers;
54      this.numProcessing = 0;
55    }
56  
57    /**
58     * @param serverName
59     * @return true if server is dead
60     */
61    public boolean isDeadServer(final String serverName) {
62      return isDeadServer(serverName, false);
63    }
64  
65    /**
66     * A dead server that comes back alive has a different start code.
67     * @param newServerName Servername as either <code>host:port</code> or
68     * <code>host,port,startcode</code>.
69     * @return true if this server was dead before and coming back alive again
70     */
71    public boolean cleanPreviousInstance(final String newServerName) {
72  
73      String serverAddress =
74          HServerInfo.getServerNameLessStartCode(newServerName);
75      for (String serverName: deadServers) {
76        String deadServerAddress =
77            HServerInfo.getServerNameLessStartCode(serverName);
78        if (deadServerAddress.equals(serverAddress)) {
79          remove(serverName);
80          return true;
81        }
82      }
83      return false;
84    }
85  
86    /**
87     * @param serverName Servername as either <code>host:port</code> or
88     * <code>host,port,startcode</code>.
89     * @param hostAndPortOnly True if <code>serverName</code> is host and
90     * port only (<code>host:port</code>) and if so, then we do a prefix compare
91     * (ignoring start codes) looking for dead server.
92     * @return true if server is dead
93     */
94    boolean isDeadServer(final String serverName, final boolean hostAndPortOnly) {
95      return HServerInfo.isServer(this, serverName, hostAndPortOnly);
96    }
97  
98    /**
99     * Checks if there are currently any dead servers being processed by the
100    * master.  Returns true if at least one region server is currently being
101    * processed as dead.
102    * @return true if any RS are being processed as dead
103    */
104   public boolean areDeadServersInProgress() {
105     return numProcessing != 0;
106   }
107 
108   public synchronized Set<String> clone() {
109     Set<String> clone = new HashSet<String>(this.deadServers.size());
110     clone.addAll(this.deadServers);
111     return clone;
112   }
113 
114   public synchronized boolean add(String e) {
115     this.numProcessing++;
116     return deadServers.add(e);
117   }
118 
119   public synchronized void finish(String e) {
120     this.numProcessing--;
121   }
122 
123   public synchronized int size() {
124     return deadServers.size();
125   }
126 
127   public synchronized boolean isEmpty() {
128     return deadServers.isEmpty();
129   }
130 
131   public synchronized boolean contains(Object o) {
132     return deadServers.contains(o);
133   }
134 
135   public Iterator<String> iterator() {
136     return this.deadServers.iterator();
137   }
138 
139   public synchronized Object[] toArray() {
140     return deadServers.toArray();
141   }
142 
143   public synchronized <T> T[] toArray(T[] a) {
144     return deadServers.toArray(a);
145   }
146 
147   public synchronized boolean remove(Object o) {
148     return this.deadServers.remove(o);
149   }
150 
151   public synchronized boolean containsAll(Collection<?> c) {
152     return deadServers.containsAll(c);
153   }
154 
155   public synchronized boolean addAll(Collection<? extends String> c) {
156     return deadServers.addAll(c);
157   }
158 
159   public synchronized boolean retainAll(Collection<?> c) {
160     return deadServers.retainAll(c);
161   }
162 
163   public synchronized boolean removeAll(Collection<?> c) {
164     return deadServers.removeAll(c);
165   }
166 
167   public synchronized void clear() {
168     throw new NotImplementedException();
169   }
170 
171   public synchronized boolean equals(Object o) {
172     return deadServers.equals(o);
173   }
174 
175   public synchronized int hashCode() {
176     return deadServers.hashCode();
177   }
178 
179   public synchronized String toString() {
180     return this.deadServers.toString();
181   }
182 }