Update of /cvsroot/freenet/freenet/src/freenet/node/http/infolets
In directory sc8-pr-cvs1:/tmp/cvs-serv4015/freenet/src/freenet/node/http/infolets
Modified Files:
GeneralInfolet.java
Log Message:
Version.java 6284
Fix bug in LoadStats.java decayingTimeWeightedAverage.
Put this node's average into the global pool, which
is checkpointed. Initialize the average from the
saved value.
Change default half life to 1.2 hours. Other nodes don't
receive updates much more frequently that that.
Change mode lines from "tabwidth: 4" to "indent-tabs-mode:
nil" since some developers don't use emacs so it is best to
use no tabs at all in the text. (Their Java IDE must also
wrap long lines in a legible manner, since they seem to
regard long lines as more legible than manually wrapped and
indented lines).
Add configuration parameter tfTolerableQueueDelay to
YThreadFactory, default 100ms.
Core.java
Mode line. Remove tabs.
Add tfTolerableQueueDelay configurable parameter.
NodeStatusServlet.java
Mode line. Remove tabs. Print the "why" data from estimatedLoad,
rejectingConnections, and rejectingRequests.
Change "Active pooled jobs" to "Pooled threads running jobs"
Change "Available threads" to "Pooled threads which are idle"
Use NumberFormat instead of ad-hoc code.
LoadStats.java
Improve display of global stats: show which were rejected
as outliers or as too old.
Make the text only dump give same info as html dump.
Carefully check the locking in LoadStats.java. In the
first cut, putting localQueryTraffic into the checkpointed
pool added a lock in a path that didn't have one before.
Make all constant class members final.
Eliminate volatile. JLS 2nd ed. gives useful semantics
for volatile, but who knows if all JVM's do it right?
Some old one's didn't. This code doesn't run often enough
for the slight speed improvement (over synchronize) to
matter.
logDEBUG, logMINOR
(LoadStats constructor) add myRef. Initialize local queries
per hour from this node's entry in the global queries per
hour.
(receivedQuery) Do not call localQueryTraffic(), which
can block on a synchronize and which does unnecessary
stuff. Just grab the data and run queriesPerHour.average
whenever timesPos wraps.
(storeTraffic) move code which cannot get IOException out of
the try/catch block. Remove the once in a lifetime call
to checkpoint() since checkpoint() now calls
storeTraffic() and hence we might already be inside
checkpoint(). The checkpoint will be done soon enough (10
minutes).
(QueryTrafficInfo) Name changed from LocalQueryTrafficInfo.
Save the local queries per hour into the global queries
per hour checkpointed list. Remove special case for early
period when there is not much data, since the average
localQueryTraffic starts from a saved value. Move the
statistics calculations from checkpoint() into this class,
so that the web page can show more information about those
calculations.
(localQueryTraffic) Remove special case for early period
when there is not much data, since the average
localQueryTraffic starts from a saved value. Never return
a value less than 1.0. Avoids testing for divide by zero
elsewhere.
(DecayingTimeWeightedAverage) Fix a really stupid bug.
Essentially, I had 1-(1/2)^(hl/dt) instead of (1/2)^(dt/hl).
It was right at hl=dt, and at dt=0 (since (1/2)^oo = 0).
But at dt < 0.2 hl, it gave no weight to the new data.
Add initial value arg to constructor. Clean up the
comments.
(globalQueryTraffic) make synchronized since class member
globalQueryTraffic is no longer marked volatile.
(shouldReset) reference resetProbability() rather than the
class member since class member is no longer volatile.
Other cosmetic changes, use logMINOR to avoid logging call
if unnecessary.
(nextCheckpoing) make synchronized. lastCheckpoint is not
volatile.
(checkpoint) Move the statistics calculations to
QueryTrafficInfo inner class constructor. Logging.
lastCheckpoint reference must be synchronized.
QueryTrafficInfo calls storeTraffic() to save the
localQueryTraffic value into the checkpoint file, so
storeTraffic() can't call checkpoint().
(dump) Print mostly the same data as dumpHtml. Use
QueryTrafficInfo to get the values.
(dumpHtml) Use QueryTrafficInfo. Include information about
which samples were too old, too small, or too big.
(LoadEntry inner class) Make all members final.
Main.java
Mode line, indenting.
(main) Copy tfTolerableQueueDelay parameter into Node. Pass
myRef to LoadStats constructor
(startNode) Pass tfTolerableQueueDelay to YThreadFactory.
Node.java
Mode line. indenting.
Add java.text.NumberFormat.
Check numbers from diagnostics for isNaN.
(static) Initialize NumberFormats. Change default
lsHalfLifeHours to 1.2 so localQueryTraffic value does
full decay in 12 hours. Reword some of the parameter
descriptions and correct some errors.
(rejectingConnections) Add an optional StringBuffer
argument, which if non-null gets filled with
details about why we are rejecting connections.
(rejectingRequests) same thing.
(estimatedLoad) same thing. Why the load is what it is.
GeneralInfolet.java
Mode line. Remove tabs. Print the "why" data from estimatedLoad,
rejectingConnections, and rejectingRequests.
Change "Active pooled jobs" to "Pooled threads running jobs"
Change "Available threads" to "Pooled threads which are idle"
Use NumberFormat instead of ad-hoc code.
FNPFeedbackToken.java
(storeData) Round the average before cast to long.
YThreadFactory.java
Add tfTolerableQueueDelay configurable parameter.
Index: GeneralInfolet.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/node/http/infolets/GeneralInfolet.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -w -r1.22 -r1.23
--- GeneralInfolet.java 24 Oct 2003 19:38:19 -0000 1.22
+++ GeneralInfolet.java 28 Oct 2003 05:10:00 -0000 1.23
@@ -1,3 +1,4 @@
+/* -*- Mode: java; c-basic-indent: 4; indent-tabs-mode: nil -*- */
package freenet.node.http.infolets;
import freenet.node.http.*;
import freenet.node.Node;
@@ -7,6 +8,7 @@
import freenet.support.servlet.*;
import freenet.Core;
import java.io.PrintWriter;
+import java.text.NumberFormat;
/**
* This is the Infolet which is displayed by default
@@ -17,13 +19,40 @@
public class GeneralInfolet extends Infolet {
private Node node;
+ private static final NumberFormat nfp;
+ private static final NumberFormat nf0;
+ private static final NumberFormat nf1;
+ private static final NumberFormat nf03;
+ private static final NumberFormat nf3;
+ static {
+ nfp = NumberFormat.getPercentInstance();
+ nfp.setMinimumFractionDigits(0);
+ nfp.setMaximumFractionDigits(1);
+ nf0 = NumberFormat.getInstance();
+ nf0.setMinimumFractionDigits(0);
+ nf0.setMaximumFractionDigits(0);
+ nf0.setGroupingUsed(false);
+ nf1 = NumberFormat.getInstance();
+ nf1.setMaximumFractionDigits(1);
+ nf1.setMinimumFractionDigits(1);
+ nf1.setGroupingUsed(false);
+ nf03 = NumberFormat.getInstance();
+ nf03.setMinimumFractionDigits(0);
+ nf03.setMaximumFractionDigits(3);
+ nf03.setGroupingUsed(false);
+ nf3 = NumberFormat.getInstance();
+ nf3.setMaximumFractionDigits(3);
+ nf3.setMinimumFractionDigits(3);
+ nf3.setGroupingUsed(false);
+ }
+
HtmlTemplate titleBoxTemplate;
/**
- * Description of the Method
+ * Return long name of the infolet
*
- * @return Description of the Return Value
+ * @return String longName
*/
public String longName() {
return "General Information";
@@ -31,9 +60,9 @@
/**
- * Description of the Method
+ * Return short name of infolet
*
- * @return Description of the Return Value
+ * @return String shortName
*/
public String shortName() {
return "general";
@@ -41,9 +70,9 @@
/**
- * Description of the Method
+ * Initialize the node reference and create the title Box template
*
- * @param n Description of the Parameter
+ * @param n The Node object this page describes.
*/
public void init(Node n) {
try {
@@ -55,6 +84,11 @@
}
+ /**
+ * Create the General Information web page
+ *
+ * @param pw The PrintWriter where the page gets written.
+ */
public void toHtml(PrintWriter pw) {
StringBuffer sb = new StringBuffer(500);
sb.append("From here you can view information about what is going ");
@@ -81,7 +115,7 @@
titleBoxTemplate.toHtml(pw);
StringBuffer uptime = new StringBuffer();
- long deltat = (System.currentTimeMillis() - Node.startupTimeMs) / 1000;
+ long deltat = (System.currentTimeMillis() - Node.startupTimeMs + 500) / 1000;
if (deltat < 60) {
uptime.append(" < 1 minute ");
@@ -127,11 +161,14 @@
// Thread load
int jobs = node.activeJobs();
int available = node.availableThreads();
- float f = node.estimatedLoad();
+ StringBuffer whyLoad = new StringBuffer(500);
+ float f = node.estimatedLoad(whyLoad);
// It's not just thread based. There's also a hard
// rate limit.
- boolean rejectingRequests = node.rejectingRequests();
- boolean rejectingConnections = node.rejectingConnections();
+ StringBuffer whyRejectingRequests = new StringBuffer(500);
+ boolean rejectingRequests = node.rejectingRequests(whyRejectingRequests);
+ StringBuffer whyRejectingConnections = new StringBuffer(500);
+ boolean rejectingConnections =
node.rejectingConnections(whyRejectingConnections);
String color = "black";
String comment = "";
@@ -149,12 +186,11 @@
int maximumThreads = node.getThreadFactory().maximumThreads();
if (maximumThreads > 0) {
- float threadPoolLoad = (((float) jobs) / maximumThreads) * 100.0f;
- msg += " (" + Float.toString(threadPoolLoad) + "%)";
+ msg += " (" + nfp.format( ((float) jobs) / maximumThreads ) + ")";
}
- sb.append("<tr><td nowrap>Active pooled jobs</td><td>" + msg + "</td></tr>");
- sb.append("<tr><td nowrap>Available threads</td><td>" + available +
"</td></tr>");
+ sb.append("<tr><td nowrap>Pooled threads running jobs</td><td>" + msg +
"</td></tr>");
+ sb.append("<tr><td nowrap>Pooled threads which are idle</td><td>" +
available + "</td></tr>");
LimitCounter outboundRequestLimit = node.outboundRequestLimit;
if(outboundRequestLimit != null)
sb.append("<tr><td nowrap>Outbound request quota used</td><td>" +
@@ -166,12 +202,20 @@
Diagnostics.MINUTE,
Diagnostics.COUNT_CHANGE)
/ 60;
- int limit = (int)(node.outputBandwidthLimit
- /* * Node.lowLevelBWLimitFudgeFactor*/);
- sb.append("<tr><td nowrap>Current upstream bandwidth usage</td><td>" +
(int)sent+
- " bytes/second ("+(int)((float)(100*sent) /
(float)limit)+"%)</td></tr>");
+ double limit = node.outputBandwidthLimit;
+ sb.append("<tr><td nowrap>Current upstream bandwidth usage</td><td>"
+ nf0.format(sent) +
+ " bytes/second (" + nfp.format(sent / limit) +
")</td></tr>");
+ }
+ if (rejectingConnections) {
+ sb.append("<tr><td>Reason for refusing connections:</td><td>");
+ sb.append(whyRejectingConnections);
+ sb.append("</td></tr>");
+ }
+ if (rejectingRequests) {
+ sb.append("<tr><td>Reason for QueryRejecting requests:</td><td>");
+ sb.append(whyRejectingRequests);
+ sb.append("</td></tr>");
}
-
if (rejectingConnections || rejectingRequests) {
sb.append("<tr><td></td><td>");
sb.append("It's normal for the node to sometimes reject connections or
requests ");
@@ -184,8 +228,8 @@
comment = " <font color=\"" + color + "\">" + comment + "</font><br>";
}
- int x = (int)(f * 1000);
- sb.append(msg + (x/10) + "." + x%10 + "%"+comment+"</td></tr>");
+ sb.append(msg + nfp.format(f) + comment + "</td></tr>");
+ sb.append("<tr><td>Reason for load:</td><td>" + whyLoad.toString() +
"</td></tr>");
sb.append("</table>");
titleBoxTemplate.set("TITLE", "Load");
titleBoxTemplate.set("CONTENT", sb.toString());
_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs