ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/client/monitors/Heartbeat__Monitor.java
Revision: 1.9
Committed: Wed Mar 7 17:18:48 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.8: +14 -12 lines
Log Message:
Added some synchronization. We managed to get a ConcurrentModificationException
in the server :)

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2     package uk.ac.ukc.iscream.client.monitors;
3    
4     //---IMPORTS---
5     import java.util.HashMap;
6     import java.util.Iterator;
7     import uk.ac.ukc.iscream.client.*;
8     import uk.ac.ukc.iscream.core.*;
9     import uk.ac.ukc.iscream.util.*;
10     import uk.ac.ukc.iscream.componentmanager.*;
11    
12     /**
13     * This Monitor watches heartbeats
14     *
15 tdb 1.7 * @author $Author: tdb1 $
16 tdb 1.9 * @version $Id: Heartbeat__Monitor.java,v 1.8 2001/03/07 01:22:47 tdb1 Exp $
17 tdb 1.1 */
18 tdb 1.7 public class Heartbeat__Monitor extends MonitorSkeleton implements Runnable {
19 tdb 1.1
20     //---FINAL ATTRIBUTES---
21    
22     /**
23     * The current CVS revision of this class
24     */
25 tdb 1.9 public final String REVISION = "$Revision: 1.8 $";
26 tdb 1.1
27     public final String DESC = "Monitors Heartbeats.";
28    
29 tdb 1.3 public final int DEFAULT_CHECK_PERIOD = 60;
30    
31 tdb 1.1 //---STATIC METHODS---
32    
33     //---CONSTRUCTORS---
34    
35 tdb 1.2 public Heartbeat__Monitor() {
36 tdb 1.3 new Thread(this).start();
37 tdb 1.2 }
38    
39 tdb 1.1 //---PUBLIC METHODS---
40    
41     public void run() {
42     ConfigurationProxy cp = ConfigurationProxy.getInstance();
43     while(true) {
44 tdb 1.3 // this cycle period of this monitor's checks
45     int checkPeriod = 0;
46     try {
47     checkPeriod = Integer.parseInt(cp.getProperty(_name, "Monitor.Heartbeat.checkPeriod"));
48     } catch (PropertyNotFoundException e) {
49     checkPeriod = DEFAULT_CHECK_PERIOD;
50     _logger.write(toString(), Logger.WARNING, "Monitor.Heartbeat.checkPeriod value unavailable using default of " + checkPeriod + " seconds");
51     } catch (NumberFormatException e) {
52     checkPeriod = DEFAULT_CHECK_PERIOD;
53     _logger.write(toString(), Logger.WARNING, "Erronous Monitor.Heartbeat.checkPeriod value in configuration using default of " + checkPeriod + " seconds");
54     }
55 tdb 1.1
56 tdb 1.9 synchronized(this) {
57     // perform the checks (use HB hash, although they *should* be the same)
58     Iterator i = _hosts.keySet().iterator();
59     while(i.hasNext()) {
60     // get host
61     String source = (String) i.next();
62     // check it
63     boolean remove = analyseHB(source);
64     if(remove) {
65     i.remove();
66     }
67 tdb 1.6 }
68 tdb 1.1 }
69    
70     // wait a while
71     try {Thread.sleep(checkPeriod * 1000);} catch (InterruptedException e) {}
72     }
73     }
74    
75 tdb 1.9 public synchronized void analysePacket(XMLPacket packet) {
76 tdb 1.1 if (packet.getParam("packet.attributes.type").equals("heartbeat")) {
77     String source = packet.getParam("packet.attributes.machine_name");
78 tdb 1.6 if (!_hosts.containsKey(source)) {
79     HashMap registerHash = new HashMap();
80     registerHash.put(source, new Register(source, _name, 1));
81     _hosts.put(source, new HeartbeatHolder(registerHash));
82 tdb 1.1 }
83 tdb 1.6 HeartbeatHolder lastHeartbeat = (HeartbeatHolder) _hosts.get(source);
84 tdb 1.2 lastHeartbeat.setLastHeartbeat(System.currentTimeMillis()/1000);
85 tdb 1.1 }
86     }
87    
88     /**
89     * Overrides the {@link java.lang.Object#toString() Object.toString()}
90     * method to provide clean logging (every class should have this).
91     *
92     * This uses the uk.ac.ukc.iscream.util.NameFormat class
93     * to format the toString()
94     *
95     * @return the name of this class and its CVS revision
96     */
97     public String toString() {
98     return FormatName.getName(
99     _name,
100     getClass().getName(),
101     REVISION);
102     }
103    
104     /**
105     * return the String representation of what the monitor does
106     */
107     public String getDescription(){
108     return DESC;
109     }
110    
111     //---PRIVATE METHODS---
112 tdb 1.7
113     private boolean analyseHB(String source) {
114     ConfigurationProxy cp = ConfigurationProxy.getInstance();
115     HeartbeatHolder hbHolder = (HeartbeatHolder) _hosts.get(source);
116     Register reg = (Register) ((HashMap) hbHolder.getRegisterHash()).get(source);
117    
118     // get host's HB interval (seconds)
119     // this should always exist, thus we set to 0
120     int hostHBinterval = 0;
121     try {
122     hostHBinterval = Integer.parseInt(cp.getProperty("Host."+source, "Host.TCPUpdateTime"));
123     } catch (PropertyNotFoundException e) {
124     hostHBinterval = 0;
125     _logger.write(toString(), Logger.WARNING, "TCPUpdateTime value unavailable using default of " + hostHBinterval + " seconds");
126     } catch (NumberFormatException e) {
127     hostHBinterval = 0;
128     _logger.write(toString(), Logger.WARNING, "Erronous TCPUpdateTime value in configuration using default of " + hostHBinterval + " seconds");
129     }
130    
131     // get host's last HB time (seconds)
132     long lastHeartbeat = hbHolder.getLastHeartbeat();
133     // time since last heartbeat (seconds)
134     long timeSinceLastHB = (System.currentTimeMillis()/1000) - lastHeartbeat;
135 tdb 1.8 // time since (or until if negative) the expected heartbeat
136     long timeSinceExpectedHB = timeSinceLastHB + (long) hostHBinterval;
137    
138     // best do a check in case the expected heartbeat is in the future
139     if(timeSinceExpectedHB < 0) {
140     timeSinceExpectedHB = 0;
141     }
142 tdb 1.7
143     // find out the threshold level we're at
144 tdb 1.8 int newThreshold = checkAttributeThreshold(timeSinceExpectedHB, reg);
145 tdb 1.7
146     // process the alert
147 tdb 1.8 processAlert(newThreshold, 0, "Heartbeat", reg, source, String.valueOf(timeSinceExpectedHB));
148 tdb 1.7
149     if(reg.getLastAlertLevel(0) == Alert.alertFINAL) {
150     return true;
151     }
152     return false;
153     }
154 tdb 1.1
155 tdb 1.2 private int checkAttributeThreshold(long timeSinceLastHB, Register reg) {
156 tdb 1.1 for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
157     if (reg.getThreshold(thresholdLevel) != -1.0) {
158 tdb 1.2 if (((long) reg.getThreshold(thresholdLevel)) < timeSinceLastHB) {
159 tdb 1.1 return thresholdLevel;
160     }
161     }
162     }
163 tdb 1.7 return Alert.thresholdNORMAL;
164 tdb 1.1 }
165    
166     //---ACCESSOR/MUTATOR METHODS---
167    
168     //---ATTRIBUTES---
169    
170     /**
171     * This is the friendly identifier of the
172     * component this class is running in.
173     * eg, a Filter may be called "filter1",
174     * If this class does not have an owning
175     * component, a name from the configuration
176     * can be placed here. This name could also
177     * be changed to null for utility classes.
178     */
179     private String _name = "Heartbeat";
180    
181     /**
182     * A reference to the configuration proxy in use
183     */
184     private ConfigurationProxy _cp = ConfigurationProxy.getInstance();
185    
186 tdb 1.6 private HashMap _hosts = new HashMap();
187 tdb 1.1
188     //---STATIC ATTRIBUTES---
189    
190     //---INNER CLASSES---
191    
192     private class HeartbeatHolder {
193    
194 tdb 1.6 public HeartbeatHolder(HashMap registerHash) {
195     _registerHash = registerHash;
196     }
197    
198 tdb 1.2 public void setLastHeartbeat(long lastHeartbeat) {
199 tdb 1.1 _lastHeartbeat = lastHeartbeat;
200     }
201    
202 tdb 1.2 public long getLastHeartbeat() {
203 tdb 1.1 return _lastHeartbeat;
204     }
205    
206 tdb 1.6 public HashMap getRegisterHash() {
207     return _registerHash;
208     }
209    
210 tdb 1.2 private long _lastHeartbeat;
211 tdb 1.6 private HashMap _registerHash;
212 tdb 1.1 }
213    
214     }