[freenet-cvs] r13462 - in trunk/freenet/src/freenet: l10n node node/useralerts support/math

nextgens at freenetproject.org nextgens at freenetproject.org
Fri Jun 1 20:51:27 UTC 2007


Author: nextgens
Date: 2007-06-01 20:51:27 +0000 (Fri, 01 Jun 2007)
New Revision: 13462

Added:
   trunk/freenet/src/freenet/node/useralerts/TimeSkewDetectedUserAlert.java
Modified:
   trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodePinger.java
   trunk/freenet/src/freenet/node/NodeStats.java
   trunk/freenet/src/freenet/node/PeerNode.java
   trunk/freenet/src/freenet/support/math/TimeDecayingRunningAverage.java
Log:
Implement a TimeSkewDetectedUserAlert... the code hasn't been tested yet

Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties	2007-06-01 20:44:14 UTC (rev 13461)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties	2007-06-01 20:51:27 UTC (rev 13462)
@@ -795,6 +795,8 @@
 TextModeClientInterfaceServer.enabledLong=Whether to enable the TMCI
 TextModeClientInterfaceServer.telnetPortNumber=Telnet port
 TextModeClientInterfaceServer.telnetPortNumberLong=Telnet port number
+TimeSkewDetectedUserAlert.title=Time skew detected!
+TimeSkewDetectedUserAlert.text=A time skew has been detected by the node. That's VERY bad. Your node won't perform correctly until it's fixed; Common causes are missconfigured powersafe mode, network time synchronization clients or buggy hardware.
 Toadlet.yes=Yes
 Toadlet.no=No
 Toadlet.cancel=Cancel

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java	2007-06-01 20:44:14 UTC (rev 13461)
+++ trunk/freenet/src/freenet/node/Node.java	2007-06-01 20:51:27 UTC (rev 13462)
@@ -88,7 +88,7 @@
 import freenet.node.useralerts.BuildOldAgeUserAlert;
 import freenet.node.useralerts.ExtOldAgeUserAlert;
 import freenet.node.useralerts.MeaningfulNodeNameUserAlert;
-import freenet.node.useralerts.N2NTMUserAlert;
+import freenet.node.useralerts.TimeSkewDetectedUserAlert;
 import freenet.node.useralerts.UserAlert;
 import freenet.pluginmanager.PluginManager;
 import freenet.store.BerkeleyDBFreenetStore;
@@ -145,6 +145,7 @@
 	
 	private static MeaningfulNodeNameUserAlert nodeNameUserAlert;
 	private static BuildOldAgeUserAlert buildOldAgeUserAlert;
+	private static TimeSkewDetectedUserAlert timeSkewDetectedUserAlert;
 	
 	public class NodeNameCallback implements StringCallback{
 			Node node;
@@ -2878,5 +2879,11 @@
 	DSASignature sign(byte[] hash) {
 		return DSA.sign(myCryptoGroup, myPrivKey, new NativeBigInteger(1, hash), random);
 	}
-
+	
+	public synchronized void setTimeSkewDetectedUserAlert() {
+		if(timeSkewDetectedUserAlert == null) {
+			timeSkewDetectedUserAlert = new TimeSkewDetectedUserAlert();
+			clientCore.alerts.register(timeSkewDetectedUserAlert);
+		}
+	}
 }

Modified: trunk/freenet/src/freenet/node/NodePinger.java
===================================================================
--- trunk/freenet/src/freenet/node/NodePinger.java	2007-06-01 20:44:14 UTC (rev 13461)
+++ trunk/freenet/src/freenet/node/NodePinger.java	2007-06-01 20:51:27 UTC (rev 13462)
@@ -22,7 +22,7 @@
 	NodePinger(Node n) {
 		this.node = n;
 		this.tdra = new TimeDecayingRunningAverage(0.0, 30*1000, // 30 seconds
-				0.0, CRAZY_MAX_PING_TIME);
+				0.0, CRAZY_MAX_PING_TIME, node);
 	}
 
 	void start() {

Modified: trunk/freenet/src/freenet/node/NodeStats.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeStats.java	2007-06-01 20:44:14 UTC (rev 13461)
+++ trunk/freenet/src/freenet/node/NodeStats.java	2007-06-01 20:51:27 UTC (rev 13462)
@@ -136,8 +136,8 @@
 	final TokenBucket requestInputThrottle;
 
 	// various metrics
-	public RunningAverage routingMissDistance = new TimeDecayingRunningAverage(0.0, 180000, 0.0, 1.0);
-	public RunningAverage backedOffPercent = new TimeDecayingRunningAverage(0.0, 180000, 0.0, 1.0);
+	public final RunningAverage routingMissDistance;
+	public final RunningAverage backedOffPercent;
 	protected final Persister persister;
 	
 	// ThreadCounting stuffs
@@ -167,13 +167,15 @@
 		this.node = node;
 		this.peers = node.peers;
 		this.hardRandom = node.random;
+		this.routingMissDistance = new TimeDecayingRunningAverage(0.0, 180000, 0.0, 1.0, node);
+		this.backedOffPercent = new TimeDecayingRunningAverage(0.0, 180000, 0.0, 1.0, node);
 		preemptiveRejectReasons = new StringCounter();
-		pInstantRejectIncoming = new TimeDecayingRunningAverage(0, 60000, 0.0, 1.0);
+		pInstantRejectIncoming = new TimeDecayingRunningAverage(0, 60000, 0.0, 1.0, node);
 		ThreadGroup tg = Thread.currentThread().getThreadGroup();
 		while(tg.getParent() != null) tg = tg.getParent();
 		this.rootThreadGroup = tg;
 		throttledPacketSendAverage =
-			new TimeDecayingRunningAverage(1, 10*60*1000 /* should be significantly longer than a typical transfer */, 0, Long.MAX_VALUE);
+			new TimeDecayingRunningAverage(1, 10*60*1000 /* should be significantly longer than a typical transfer */, 0, Long.MAX_VALUE, node);
 		nodePinger = new NodePinger(node);
 
 		previous_input_stat = 0;
@@ -269,32 +271,32 @@
 		if(logMINOR) Logger.minor(this, "Read throttleFS:\n"+throttleFS);
 		
 		// Guesstimates. Hopefully well over the reality.
-		localChkFetchBytesSentAverage = new TimeDecayingRunningAverage(500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkFetchBytesSentAverage"));
-		localSskFetchBytesSentAverage = new TimeDecayingRunningAverage(500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalSskFetchBytesSentAverage"));
-		localChkInsertBytesSentAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkInsertBytesSentAverage"));
-		localSskInsertBytesSentAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalSskInsertBytesSentAverage"));
-		localChkFetchBytesReceivedAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkFetchBytesReceivedAverage"));
-		localSskFetchBytesReceivedAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalSskFetchBytesReceivedAverage"));
-		localChkInsertBytesReceivedAverage = new TimeDecayingRunningAverage(1024, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkInsertBytesReceivedAverage"));
-		localSskInsertBytesReceivedAverage = new TimeDecayingRunningAverage(500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkInsertBytesReceivedAverage"));
+		localChkFetchBytesSentAverage = new TimeDecayingRunningAverage(500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkFetchBytesSentAverage"), node);
+		localSskFetchBytesSentAverage = new TimeDecayingRunningAverage(500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalSskFetchBytesSentAverage"), node);
+		localChkInsertBytesSentAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkInsertBytesSentAverage"), node);
+		localSskInsertBytesSentAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalSskInsertBytesSentAverage"), node);
+		localChkFetchBytesReceivedAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkFetchBytesReceivedAverage"), node);
+		localSskFetchBytesReceivedAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalSskFetchBytesReceivedAverage"), node);
+		localChkInsertBytesReceivedAverage = new TimeDecayingRunningAverage(1024, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkInsertBytesReceivedAverage"), node);
+		localSskInsertBytesReceivedAverage = new TimeDecayingRunningAverage(500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("LocalChkInsertBytesReceivedAverage"), node);
 
-		remoteChkFetchBytesSentAverage = new TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkFetchBytesSentAverage"));
-		remoteSskFetchBytesSentAverage = new TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskFetchBytesSentAverage"));
-		remoteChkInsertBytesSentAverage = new TimeDecayingRunningAverage(32768+32768+1024, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkInsertBytesSentAverage"));
-		remoteSskInsertBytesSentAverage = new TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskInsertBytesSentAverage"));
-		remoteChkFetchBytesReceivedAverage = new TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkFetchBytesReceivedAverage"));
-		remoteSskFetchBytesReceivedAverage = new TimeDecayingRunningAverage(2048+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskFetchBytesReceivedAverage"));
-		remoteChkInsertBytesReceivedAverage = new TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkInsertBytesReceivedAverage"));
-		remoteSskInsertBytesReceivedAverage = new TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskInsertBytesReceivedAverage"));
+		remoteChkFetchBytesSentAverage = new TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkFetchBytesSentAverage"), node);
+		remoteSskFetchBytesSentAverage = new TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskFetchBytesSentAverage"), node);
+		remoteChkInsertBytesSentAverage = new TimeDecayingRunningAverage(32768+32768+1024, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkInsertBytesSentAverage"), node);
+		remoteSskInsertBytesSentAverage = new TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskInsertBytesSentAverage"), node);
+		remoteChkFetchBytesReceivedAverage = new TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkFetchBytesReceivedAverage"), node);
+		remoteSskFetchBytesReceivedAverage = new TimeDecayingRunningAverage(2048+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskFetchBytesReceivedAverage"), node);
+		remoteChkInsertBytesReceivedAverage = new TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteChkInsertBytesReceivedAverage"), node);
+		remoteSskInsertBytesReceivedAverage = new TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("RemoteSskInsertBytesReceivedAverage"), node);
 		
-		successfulChkFetchBytesSentAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkFetchBytesSentAverage"));
-		successfulSskFetchBytesSentAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskFetchBytesSentAverage"));
-		successfulChkInsertBytesSentAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkInsertBytesSentAverage"));
-		successfulSskInsertBytesSentAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskInsertBytesSentAverage"));
-		successfulChkFetchBytesReceivedAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkFetchBytesReceivedAverage"));
-		successfulSskFetchBytesReceivedAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskFetchBytesReceivedAverage"));
-		successfulChkInsertBytesReceivedAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkInsertBytesReceivedAverage"));
-		successfulSskInsertBytesReceivedAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskInsertBytesReceivedAverage"));
+		successfulChkFetchBytesSentAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkFetchBytesSentAverage"), node);
+		successfulSskFetchBytesSentAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskFetchBytesSentAverage"), node);
+		successfulChkInsertBytesSentAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkInsertBytesSentAverage"), node);
+		successfulSskInsertBytesSentAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskInsertBytesSentAverage"), node);
+		successfulChkFetchBytesReceivedAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkFetchBytesReceivedAverage"), node);
+		successfulSskFetchBytesReceivedAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskFetchBytesReceivedAverage"), node);
+		successfulChkInsertBytesReceivedAverage = new TimeDecayingRunningAverage(32768, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulChkInsertBytesReceivedAverage"), node);
+		successfulSskInsertBytesReceivedAverage = new TimeDecayingRunningAverage(2048, 180000, 0.0, 1024*1024*1024, throttleFS == null ? null : throttleFS.subset("SuccessfulSskInsertBytesReceivedAverage"), node);
 		
 		requestOutputThrottle = 
 			new TokenBucket(Math.max(obwLimit*60, 32768*20), (int)((1000L*1000L*1000L) / (obwLimit * FRACTION_OF_BANDWIDTH_USED_BY_REQUESTS)), 0);

Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java	2007-06-01 20:44:14 UTC (rev 13461)
+++ trunk/freenet/src/freenet/node/PeerNode.java	2007-06-01 20:51:27 UTC (rev 13462)
@@ -362,6 +362,7 @@
     	logMINOR = Logger.shouldLog(Logger.MINOR, this);
         this.node = node2;
         this.peers = peers;
+        this.backedOffPercent = new TimeDecayingRunningAverage(0.0, 180000, 0.0, 1.0, node);
         String identityString = fs.get("identity");
     	if(identityString == null)
     		throw new PeerParseException("No identity!");
@@ -535,11 +536,11 @@
         // A SimpleRunningAverage would be a bad choice because it would cause oscillations.
         // So go for a filter.
         pingAverage = 
-        	new TimeDecayingRunningAverage(1, 600*1000 /* should be significantly longer than a typical transfer */, 0, NodePinger.CRAZY_MAX_PING_TIME);
+        	new TimeDecayingRunningAverage(1, 600*1000 /* should be significantly longer than a typical transfer */, 0, NodePinger.CRAZY_MAX_PING_TIME, node);
 
         // TDRA for probability of rejection
         pRejected =
-        	new TimeDecayingRunningAverage(0, 600*1000, 0.0, 1.0);
+        	new TimeDecayingRunningAverage(0, 600*1000, 0.0, 1.0, node);
         
         // ARK stuff.
 
@@ -2139,7 +2140,7 @@
 	/** Previous backoff reason (used by setPeerNodeStatus)*/
 	String previousRoutingBackoffReason;
 	/* percent of time this peer is backed off */
-	public RunningAverage backedOffPercent = new TimeDecayingRunningAverage(0.0, 180000, 0.0, 1.0);
+	public final RunningAverage backedOffPercent;
 	/* time of last sample */
 	private long lastSampleTime = Long.MAX_VALUE;
     

Added: trunk/freenet/src/freenet/node/useralerts/TimeSkewDetectedUserAlert.java
===================================================================
--- trunk/freenet/src/freenet/node/useralerts/TimeSkewDetectedUserAlert.java	                        (rev 0)
+++ trunk/freenet/src/freenet/node/useralerts/TimeSkewDetectedUserAlert.java	2007-06-01 20:51:27 UTC (rev 13462)
@@ -0,0 +1,63 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package freenet.node.useralerts;
+
+import freenet.l10n.L10n;
+import freenet.support.HTMLNode;
+
+/**
+ * A simple user alert warning the user about the weird effect a time skew
+ * can have on a freenet node.
+ *
+ * This useralert is SET only and can be triggered from NodeStarter
+ *
+ * @author Florent Daignière <nextgens at freenetproject.org>
+ */
+public class TimeSkewDetectedUserAlert implements UserAlert {
+	private boolean isValid=false;
+	
+	public boolean userCanDismiss() {
+		return false;
+	}
+
+	public String getTitle() {
+		return l10n("title");
+	}
+	
+	private String l10n(String key) {
+		return L10n.getString("TimeSkewDetectedUserAlert."+key);
+	}
+
+	public String getText() {
+		return l10n("text");
+	}
+
+	public HTMLNode getHTMLText() {
+		return new HTMLNode("div", getText());
+	}
+
+	public short getPriorityClass() {
+		return UserAlert.CRITICAL_ERROR;
+	}
+
+	public boolean isValid() {
+		return isValid;
+	}
+	
+	public void isValid(boolean b){
+		if(userCanDismiss()) isValid=b;
+	}
+	
+	public String dismissButtonText(){
+		return L10n.getString("UserAlert.hide");
+	}
+	
+	public boolean shouldUnregisterOnDismiss() {
+		return false;
+	}
+	
+	public void onDismiss() {
+		// can't happen!
+	}
+}

Modified: trunk/freenet/src/freenet/support/math/TimeDecayingRunningAverage.java
===================================================================
--- trunk/freenet/src/freenet/support/math/TimeDecayingRunningAverage.java	2007-06-01 20:44:14 UTC (rev 13461)
+++ trunk/freenet/src/freenet/support/math/TimeDecayingRunningAverage.java	2007-06-01 20:51:27 UTC (rev 13462)
@@ -7,6 +7,7 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+import freenet.node.Node;
 import freenet.support.Logger;
 import freenet.support.SimpleFieldSet;
 
@@ -40,6 +41,7 @@
     double minReport;
     double maxReport;
     boolean logDEBUG;
+    private final Node node;
     
     public String toString() {
 		long now = System.currentTimeMillis();
@@ -53,7 +55,7 @@
     }
     
     public TimeDecayingRunningAverage(double defaultValue, long halfLife,
-            double min, double max) {
+            double min, double max, final Node node) {
     	curValue = defaultValue;
         this.defaultValue = defaultValue;
         started = false;
@@ -66,10 +68,11 @@
         if(logDEBUG)
         	Logger.debug(this, "Created "+this,
         			new Exception("debug"));
+        this.node = node;
     }
     
     public TimeDecayingRunningAverage(double defaultValue, long halfLife,
-            double min, double max, SimpleFieldSet fs) {
+            double min, double max, SimpleFieldSet fs, final Node node) {
     	curValue = defaultValue;
         this.defaultValue = defaultValue;
         started = false;
@@ -98,9 +101,10 @@
         		}
         	}
         }
+        this.node = node;
     }
     
-    public TimeDecayingRunningAverage(double defaultValue, double halfLife, double min, double max, DataInputStream dis) throws IOException {
+    public TimeDecayingRunningAverage(double defaultValue, double halfLife, double min, double max, DataInputStream dis, final Node node) throws IOException {
         int m = dis.readInt();
         if(m != MAGIC) throw new IOException("Invalid magic "+m);
         int v = dis.readInt();
@@ -120,6 +124,7 @@
         lastReportTime = -1;
         createdTime = System.currentTimeMillis() - priorExperienceTime;
         totalReports = dis.readLong();
+        this.node = node;
     }
 
     public TimeDecayingRunningAverage(TimeDecayingRunningAverage a) {
@@ -132,6 +137,7 @@
         this.started = a.started;
         this.totalReports = a.totalReports;
         this.curValue = a.curValue;
+        this.node = a.node;
     }
 
     public synchronized double currentValue() {
@@ -165,13 +171,17 @@
 					 now - lastReportTime;
 				long uptime = now - createdTime;
 				if(thisInterval < 0) {
-					Logger.error(this, "Clock (reporting) went back in time, ignoring report: "+now+" was "+lastReportTime+" (back "+(-thisInterval)+"ms");
+					Logger.error(this, "Clock (reporting) went back in time, ignoring report: "+now+" was "+lastReportTime+" (back "+(-thisInterval)+"ms)");
 					lastReportTime = now;
+					if(node != null)
+						node.setTimeSkewDetectedUserAlert();
 					return;
 				}
 				double thisHalfLife = halfLife;
 				if(uptime < 0) {
-					Logger.error(this, "Clock (uptime) went back in time, ignoring report: "+now+" was "+createdTime+" (back "+(-uptime)+"ms");
+					Logger.error(this, "Clock (uptime) went back in time, ignoring report: "+now+" was "+createdTime+" (back "+(-uptime)+"ms)");
+					if(node != null)
+						node.setTimeSkewDetectedUserAlert();
 					return;
 				} else {
 					if((uptime / 4) < thisHalfLife) thisHalfLife = (uptime / 4);




More information about the cvs mailing list