Author: toad
Date: 2007-03-22 20:37:23 +0000 (Thu, 22 Mar 2007)
New Revision: 12277
Added:
trunk/freenet/src/freenet/node/ConfigurablePersister.java
trunk/freenet/src/freenet/node/NodeStats.java
trunk/freenet/src/freenet/node/Persistable.java
trunk/freenet/src/freenet/node/Persister.java
Modified:
trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
trunk/freenet/src/freenet/config/SubConfig.java
trunk/freenet/src/freenet/node/InsertHandler.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/NodeClientCore.java
trunk/freenet/src/freenet/node/NodeDispatcher.java
trunk/freenet/src/freenet/node/PacketSender.java
trunk/freenet/src/freenet/node/PeerManager.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/node/RequestHandler.java
trunk/freenet/src/freenet/node/RequestStarter.java
trunk/freenet/src/freenet/node/RequestStarterGroup.java
trunk/freenet/src/freenet/node/SSKInsertHandler.java
trunk/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java
Log:
Major refactoring:
- Move most stats into NodeStats
- Move peers-related stats into PeerManager
- Separate node and client throttles
- Persistable/Persister
Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2007-03-22 19:16:22 UTC (rev 12276)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
2007-03-22 20:37:23 UTC (rev 12277)
@@ -26,6 +26,8 @@
import freenet.node.FSParseException;
import freenet.node.Node;
import freenet.node.NodeClientCore;
+import freenet.node.NodeStats;
+import freenet.node.PeerManager;
import freenet.node.PeerNode;
import freenet.node.PeerNodeStatus;
import freenet.node.Version;
@@ -41,12 +43,16 @@
private final Node node;
private final NodeClientCore core;
+ private final NodeStats stats;
+ private final PeerManager peers;
private boolean isReversed = false;
protected DarknetConnectionsToadlet(Node n, NodeClientCore core,
HighLevelSimpleClient client) {
super(client);
this.node = n;
this.core = core;
+ this.stats = n.nodeStats;
+ this.peers = n.peers;
}
public String supportedMethods() {
@@ -72,7 +78,7 @@
final boolean fProxyJavascriptEnabled =
node.isFProxyJavascriptEnabled();
/* gather connection statistics */
- PeerNodeStatus[] peerNodeStatuses = node.getPeerNodeStatuses();
+ PeerNodeStatus[] peerNodeStatuses = peers.getPeerNodeStatuses();
Arrays.sort(peerNodeStatuses, new Comparator() {
public int compare(Object first, Object second) {
int result = 0;
@@ -118,16 +124,16 @@
}
});
- int numberOfConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_CONNECTED);
- int numberOfRoutingBackedOff =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
- int numberOfTooNew =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_TOO_NEW);
- int numberOfTooOld =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_TOO_OLD);
- int numberOfDisconnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_DISCONNECTED);
- int numberOfNeverConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_NEVER_CONNECTED);
- int numberOfDisabled =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_DISABLED);
- int numberOfBursting =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_BURSTING);
- int numberOfListening =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_LISTENING);
- int numberOfListenOnly =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_LISTEN_ONLY);
+ int numberOfConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_CONNECTED);
+ int numberOfRoutingBackedOff =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
+ int numberOfTooNew =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_TOO_NEW);
+ int numberOfTooOld =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_TOO_OLD);
+ int numberOfDisconnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISCONNECTED);
+ int numberOfNeverConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED);
+ int numberOfDisabled =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISABLED);
+ int numberOfBursting =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_BURSTING);
+ int numberOfListening =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_LISTENING);
+ int numberOfListenOnly =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_LISTEN_ONLY);
int numberOfSimpleConnected = numberOfConnected +
numberOfRoutingBackedOff;
int numberOfNotConnected = numberOfTooNew + numberOfTooOld +
numberOfDisconnected + numberOfNeverConnected + numberOfDisabled +
numberOfBursting + numberOfListening + numberOfListenOnly;
@@ -150,17 +156,17 @@
/* node status values */
long nodeUptimeSeconds = (now - node.startupTime) /
1000;
- int bwlimitDelayTime = (int) node.getBwlimitDelayTime();
- int nodeAveragePingTime = (int)
node.getNodeAveragePingTime();
- int networkSizeEstimateSession =
node.getNetworkSizeEstimate(-1);
+ int bwlimitDelayTime = (int)
stats.getBwlimitDelayTime();
+ int nodeAveragePingTime = (int)
stats.getNodeAveragePingTime();
+ int networkSizeEstimateSession =
stats.getNetworkSizeEstimate(-1);
int networkSizeEstimateRecent = 0;
if(nodeUptimeSeconds > (48*60*60)) { // 48 hours
- networkSizeEstimateRecent =
node.getNetworkSizeEstimate(now - (48*60*60*1000)); // 48 hours
+ networkSizeEstimateRecent =
stats.getNetworkSizeEstimate(now - (48*60*60*1000)); // 48 hours
}
DecimalFormat fix4 = new DecimalFormat("0.0000");
- double routingMissDistance =
node.routingMissDistance.currentValue();
+ double routingMissDistance =
stats.routingMissDistance.currentValue();
DecimalFormat fix1 = new DecimalFormat("##0.0%");
- double backedOffPercent =
node.backedOffPercent.currentValue();
+ double backedOffPercent =
stats.backedOffPercent.currentValue();
String nodeUptimeString =
TimeUtil.formatTime(nodeUptimeSeconds * 1000); // *1000 to convert to
milliseconds
// BEGIN OVERVIEW TABLE
@@ -183,7 +189,7 @@
overviewList.addChild("li", "nodeUptime:\u00a0"
+ nodeUptimeString);
overviewList.addChild("li",
"routingMissDistance:\u00a0" + fix4.format(routingMissDistance));
overviewList.addChild("li",
"backedOffPercent:\u00a0" + fix1.format(backedOffPercent));
- overviewList.addChild("li",
"pInstantReject:\u00a0" + fix1.format(node.pRejectIncomingInstantly()));
+ overviewList.addChild("li",
"pInstantReject:\u00a0" + fix1.format(stats.pRejectIncomingInstantly()));
nextTableCell = overviewTableRow.addChild("td");
}
@@ -222,7 +228,7 @@
activityList.addChild("li", "Total
Output:\u00a0" + SizeUtil.formatSize(total[0], true) + "\u00a0(" +
SizeUtil.formatSize(total_output_rate, true) + "ps)");
activityList.addChild("li", "Payload
Output:\u00a0" + SizeUtil.formatSize(totalPayload, true) + "\u00a0(" +
SizeUtil.formatSize(total_payload_rate, true) + "ps) ("+percent+"%)");
activityList.addChild("li", "Total
Input:\u00a0" + SizeUtil.formatSize(total[1], true) + "\u00a0(" +
SizeUtil.formatSize(total_input_rate, true) + "ps)");
- long[] rate = node.getNodeIOStats();
+ long[] rate = stats.getNodeIOStats();
long delta = (rate[5] - rate[2]) / 1000;
if(delta > 0) {
long output_rate = (rate[3] -
rate[0]) / delta;
@@ -303,13 +309,13 @@
HTMLNode backoffReasonInfobox =
nextTableCell.addChild("div", "class", "infobox");
backoffReasonInfobox.addChild("div", "class",
"infobox-header", "Peer backoff reasons");
HTMLNode backoffReasonContent =
backoffReasonInfobox.addChild("div", "class", "infobox-content");
- String [] routingBackoffReasons =
node.getPeerNodeRoutingBackoffReasons();
+ String [] routingBackoffReasons =
peers.getPeerNodeRoutingBackoffReasons();
if(routingBackoffReasons.length == 0) {
backoffReasonContent.addChild("#",
"Good, your node is not backed off from any peers!");
} else {
HTMLNode reasonList =
backoffReasonContent.addChild("ul");
for(int
i=0;i<routingBackoffReasons.length;i++) {
- int reasonCount =
node.getPeerNodeRoutingBackoffReasonSize(routingBackoffReasons[i]);
+ int reasonCount =
peers.getPeerNodeRoutingBackoffReasonSize(routingBackoffReasons[i]);
if(reasonCount > 0) {
reasonList.addChild("li", routingBackoffReasons[i] + '\u00a0' + reasonCount);
}
@@ -400,7 +406,7 @@
// status column
String statusString =
peerNodeStatus.getStatusName();
- if (!advancedModeEnabled &&
(peerNodeStatus.getStatusValue() == Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF)) {
+ if (!advancedModeEnabled &&
(peerNodeStatus.getStatusValue() ==
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF)) {
statusString = "BUSY";
}
peerRow.addChild("td", "class",
"peer-status").addChild("span", "class", peerNodeStatus.getStatusCSSName(),
statusString + (peerNodeStatus.isFetchingARK() ? "*" : ""));
@@ -418,7 +424,7 @@
}
// version column
- if (peerNodeStatus.getStatusValue() !=
Node.PEER_NODE_STATUS_NEVER_CONNECTED &&
(peerNodeStatus.isPublicInvalidVersion() ||
peerNodeStatus.isPublicReverseInvalidVersion())) { // Don't draw attention to
a version problem if NEVER CONNECTED
+ if (peerNodeStatus.getStatusValue() !=
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED &&
(peerNodeStatus.isPublicInvalidVersion() ||
peerNodeStatus.isPublicReverseInvalidVersion())) { // Don't draw attention to
a version problem if NEVER CONNECTED
peerRow.addChild("td", "class",
"peer-version").addChild("span", "class", "peer_version_problem",
peerNodeStatus.getSimpleVersion());
} else {
peerRow.addChild("td", "class",
"peer-version").addChild("#", peerNodeStatus.getSimpleVersion());
@@ -450,7 +456,7 @@
long idle =
peerNodeStatus.getTimeLastRoutable();
if (peerNodeStatus.isRoutable()) {
idle =
peerNodeStatus.getTimeLastConnectionCompleted();
- } else if
(peerNodeStatus.getStatusValue() == Node.PEER_NODE_STATUS_NEVER_CONNECTED) {
+ } else if
(peerNodeStatus.getStatusValue() ==
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED) {
idle =
peerNodeStatus.getPeerAddedTime();
}
if(!peerNodeStatus.isConnected() &&
(now - idle) > (2 * 7 * 24 * 60 * 60 * (long) 1000)) { // 2 weeks
@@ -899,7 +905,7 @@
PeerNode[] peerNodes = node.getDarknetConnections();
for(int i = 0; i < peerNodes.length; i++) {
if
(request.isPartSet("node_"+peerNodes[i].hashCode())) {
-
if((peerNodes[i].timeLastConnectionCompleted() < (System.currentTimeMillis() -
1000*60*60*24*7) /* one week */) || (peerNodes[i].peerNodeStatus ==
Node.PEER_NODE_STATUS_NEVER_CONNECTED) || request.isPartSet("forceit")){
+
if((peerNodes[i].timeLastConnectionCompleted() < (System.currentTimeMillis() -
1000*60*60*24*7) /* one week */) || (peerNodes[i].peerNodeStatus ==
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED) || request.isPartSet("forceit")){
this.node.removeDarknetConnection(peerNodes[i]);
if(logMINOR) Logger.minor(this,
"Removed node: node_"+peerNodes[i].hashCode());
}else{
Modified: trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java 2007-03-22
19:16:22 UTC (rev 12276)
+++ trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java 2007-03-22
20:37:23 UTC (rev 12277)
@@ -15,6 +15,7 @@
import freenet.io.comm.UdpSocketManager;
import freenet.node.Node;
import freenet.node.NodeClientCore;
+import freenet.node.PeerManager;
import freenet.node.PeerNode;
import freenet.support.Base64;
import freenet.support.HTMLNode;
@@ -153,7 +154,7 @@
fs.removeValue("sentTime");
pn.queueN2NTM(fs);
Logger.normal(this,
"Queued N2NTM to '"+pn.getName()+"': "+message);
- } else
if(pn.getPeerNodeStatus() == Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF) {
+ } else
if(pn.getPeerNodeStatus() == PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF) {
sendStatusShort =
"Delayed";
sendStatusLong =
"Backed off: Sending of message possibly delayed to peer";
sendStatusClass =
"n2ntm-send-delayed";
Modified: trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
2007-03-22 19:16:22 UTC (rev 12276)
+++ trunk/freenet/src/freenet/clients/http/StatisticsToadlet.java
2007-03-22 20:37:23 UTC (rev 12277)
@@ -19,6 +19,7 @@
import freenet.node.Node;
import freenet.node.NodeClientCore;
import freenet.node.NodeStarter;
+import freenet.node.NodeStats;
import freenet.node.PeerManager;
import freenet.node.PeerNodeStatus;
import freenet.node.RequestStarterGroup;
@@ -58,11 +59,15 @@
private final Node node;
private final NodeClientCore core;
+ private final NodeStats stats;
+ private final PeerManager peers;
protected StatisticsToadlet(Node n, NodeClientCore core,
HighLevelSimpleClient client) {
super(client);
this.node = n;
this.core = core;
+ stats = node.nodeStats;
+ peers = node.peers;
}
public String supportedMethods() {
@@ -97,7 +102,7 @@
final SubConfig nodeConfig = node.config.get("node");
/* gather connection statistics */
- PeerNodeStatus[] peerNodeStatuses = node.getPeerNodeStatuses();
+ PeerNodeStatus[] peerNodeStatuses = peers.getPeerNodeStatuses();
Arrays.sort(peerNodeStatuses, new Comparator() {
public int compare(Object first, Object second) {
PeerNodeStatus firstNode = (PeerNodeStatus)
first;
@@ -110,16 +115,16 @@
}
});
- int numberOfConnected = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_CONNECTED);
- int numberOfRoutingBackedOff =
getPeerStatusCount(peerNodeStatuses, Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
- int numberOfTooNew = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_TOO_NEW);
- int numberOfTooOld = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_TOO_OLD);
- int numberOfDisconnected = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_DISCONNECTED);
- int numberOfNeverConnected =
getPeerStatusCount(peerNodeStatuses, Node.PEER_NODE_STATUS_NEVER_CONNECTED);
- int numberOfDisabled = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_DISABLED);
- int numberOfBursting = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_BURSTING);
- int numberOfListening = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_LISTENING);
- int numberOfListenOnly = getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_LISTEN_ONLY);
+ int numberOfConnected = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_CONNECTED);
+ int numberOfRoutingBackedOff =
getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
+ int numberOfTooNew = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_TOO_NEW);
+ int numberOfTooOld = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_TOO_OLD);
+ int numberOfDisconnected = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISCONNECTED);
+ int numberOfNeverConnected =
getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED);
+ int numberOfDisabled = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISABLED);
+ int numberOfBursting = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_BURSTING);
+ int numberOfListening = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_LISTENING);
+ int numberOfListenOnly = getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_LISTEN_ONLY);
HTMLNode pageNode = ctx.getPageMaker().getPageNode("Statistics
for " + node.getMyName(), ctx);
HTMLNode contentNode =
ctx.getPageMaker().getContentNode(pageNode);
@@ -136,26 +141,26 @@
/* node status values */
long nodeUptimeSeconds = (now - node.startupTime) /
1000;
- int bwlimitDelayTime = (int) node.getBwlimitDelayTime();
- int nodeAveragePingTime = (int)
node.getNodeAveragePingTime();
- int networkSizeEstimateSession =
node.getNetworkSizeEstimate(-1);
+ int bwlimitDelayTime = (int)
stats.getBwlimitDelayTime();
+ int nodeAveragePingTime = (int)
stats.getNodeAveragePingTime();
+ int networkSizeEstimateSession =
stats.getNetworkSizeEstimate(-1);
int networkSizeEstimate24h = 0;
int networkSizeEstimate48h = 0;
double numberOfRemotePeerLocationsSeenInSwaps =
(double)node.getNumberOfRemotePeerLocationsSeenInSwaps();
if(nodeUptimeSeconds > (24*60*60)) { // 24 hours
- networkSizeEstimate24h =
node.getNetworkSizeEstimate(now - (24*60*60*1000)); // 48 hours
+ networkSizeEstimate24h =
stats.getNetworkSizeEstimate(now - (24*60*60*1000)); // 48 hours
}
if(nodeUptimeSeconds > (48*60*60)) { // 48 hours
- networkSizeEstimate48h =
node.getNetworkSizeEstimate(now - (48*60*60*1000)); // 48 hours
+ networkSizeEstimate48h =
stats.getNetworkSizeEstimate(now - (48*60*60*1000)); // 48 hours
}
DecimalFormat fix1p4 = new DecimalFormat("0.0000");
DecimalFormat fix6p6 = new
DecimalFormat("#####0.0#####");
DecimalFormat fix1p6sci = new
DecimalFormat("0.######E0");
DecimalFormat fix3p1pct = new DecimalFormat("##0.0%");
NumberFormat thousendPoint = NumberFormat.getInstance();
- double routingMissDistance =
node.routingMissDistance.currentValue();
- double backedOffPercent =
node.backedOffPercent.currentValue();
+ double routingMissDistance =
stats.routingMissDistance.currentValue();
+ double backedOffPercent =
stats.backedOffPercent.currentValue();
String nodeUptimeString =
TimeUtil.formatTime(nodeUptimeSeconds * 1000); // *1000 to convert to
milliseconds
HTMLNode overviewTable = contentNode.addChild("table",
"class", "column");
@@ -183,7 +188,7 @@
overviewList.addChild("li", "nodeUptime:\u00a0"
+ nodeUptimeString);
overviewList.addChild("li",
"routingMissDistance:\u00a0" + fix1p4.format(routingMissDistance));
overviewList.addChild("li",
"backedOffPercent:\u00a0" + fix3p1pct.format(backedOffPercent));
- overviewList.addChild("li",
"pInstantReject:\u00a0" + fix3p1pct.format(node.pRejectIncomingInstantly()));
+ overviewList.addChild("li",
"pInstantReject:\u00a0" + fix3p1pct.format(stats.pRejectIncomingInstantly()));
overviewList.addChild("li",
"unclaimedFIFOSize:\u00a0" + node.getUnclaimedFIFOSize());
nextTableCell = overviewTableRow.addChild("td");
}
@@ -284,13 +289,13 @@
HTMLNode backoffReasonInfobox =
nextTableCell.addChild("div", "class", "infobox");
backoffReasonInfobox.addChild("div", "class",
"infobox-header", "Peer backoff reasons");
HTMLNode backoffReasonContent =
backoffReasonInfobox.addChild("div", "class", "infobox-content");
- String [] routingBackoffReasons =
node.getPeerNodeRoutingBackoffReasons();
+ String [] routingBackoffReasons =
peers.getPeerNodeRoutingBackoffReasons();
if(routingBackoffReasons.length == 0) {
backoffReasonContent.addChild("#",
"Good, your node is not backed off from any peers!");
} else {
HTMLNode reasonList =
backoffReasonContent.addChild("ul");
for(int
i=0;i<routingBackoffReasons.length;i++) {
- int reasonCount =
node.getPeerNodeRoutingBackoffReasonSize(routingBackoffReasons[i]);
+ int reasonCount =
peers.getPeerNodeRoutingBackoffReasonSize(routingBackoffReasons[i]);
if(reasonCount > 0) {
reasonList.addChild("li", routingBackoffReasons[i] + '\u00a0' + reasonCount);
}
@@ -368,7 +373,7 @@
bandwidthList.addChild("li", "Total
Output:\u00a0" + SizeUtil.formatSize(total[0]) + " (" +
SizeUtil.formatSize(total_output_rate, true) + "ps)");
bandwidthList.addChild("li", "Payload
Output:\u00a0" + SizeUtil.formatSize(totalPayload) + " (" +
SizeUtil.formatSize(total_payload_rate, true) + "ps) ("+percent+"%)");
bandwidthList.addChild("li", "Total
Input:\u00a0" + SizeUtil.formatSize(total[1]) + " (" +
SizeUtil.formatSize(total_input_rate, true) + "ps)");
- long[] rate = node.getNodeIOStats();
+ long[] rate = stats.getNodeIOStats();
long delta = (rate[5] - rate[2]) / 1000;
if(delta > 0) {
long output_rate = (rate[3] - rate[0])
/ delta;
@@ -462,12 +467,12 @@
long maxJavaMem = (long)maxMemory;
int availableCpus = rt.availableProcessors();
- int threadCount = node.getActiveThreadCount();
+ int threadCount = stats.getActiveThreadCount();
jvmStatsList.addChild("li", "Used Java
memory:\u00a0" + SizeUtil.formatSize(usedJavaMem, true));
jvmStatsList.addChild("li", "Allocated Java
memory:\u00a0" + SizeUtil.formatSize(allocatedJavaMem, true));
jvmStatsList.addChild("li", "Maximum Java
memory:\u00a0" + SizeUtil.formatSize(maxJavaMem, true));
- jvmStatsList.addChild("li", "Running
threads:\u00a0" + thousendPoint.format(threadCount) + '/' +
node.getThreadLimit());
+ jvmStatsList.addChild("li", "Running
threads:\u00a0" + thousendPoint.format(threadCount) + '/' +
stats.getThreadLimit());
jvmStatsList.addChild("li", "Available
CPUs:\u00a0" + availableCpus);
jvmStatsList.addChild("li", "JVM Vendor:\u00a0"
+ System.getProperty("java.vm.vendor"));
jvmStatsList.addChild("li", "JVM
Version:\u00a0" + System.getProperty("java.vm.version"));
@@ -609,7 +614,7 @@
nodeCircleInfoboxContent.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.875, false,
1.0), "mark" }, "+");
nodeCircleInfoboxContent.addChild("span", new String[] {
"style", "class" }, new String[] { generatePeerCircleStyleString(0.875, false,
1.0), "mark" }, "+");
nodeCircleInfoboxContent.addChild("span", new String[] {
"style", "class" }, new String[] { "position: absolute; top: " +
PEER_CIRCLE_RADIUS + "px; left: " + (PEER_CIRCLE_RADIUS +
PEER_CIRCLE_ADDITIONAL_FREE_SPACE) + "px", "mark" }, "+");
- final Object[] knownLocsCopy = node.getKnownLocations(-1);
+ final Object[] knownLocsCopy = stats.getKnownLocations(-1);
final Double[] locations = (Double[])knownLocsCopy[0];
final Long[] timestamps = (Long[])knownLocsCopy[1];
Double location;
@@ -669,7 +674,7 @@
peerCircleInfoboxContent.addChild("span", new String[] {
"style", "class" }, new String[] { "position: absolute; top: " +
PEER_CIRCLE_RADIUS + "px; left: " + (PEER_CIRCLE_RADIUS +
PEER_CIRCLE_ADDITIONAL_FREE_SPACE) + "px", "mark" }, "+");
//
double myLocation = node.getLocation();
- PeerNodeStatus[] peerNodeStatuses = node.getPeerNodeStatuses();
+ PeerNodeStatus[] peerNodeStatuses = peers.getPeerNodeStatuses();
PeerNodeStatus peerNodeStatus;
double peerLocation;
double peerDistance;
Modified: trunk/freenet/src/freenet/config/SubConfig.java
===================================================================
--- trunk/freenet/src/freenet/config/SubConfig.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/config/SubConfig.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -302,4 +302,10 @@
}
}
+ public String getRawOption(String name) {
+ if(config instanceof PersistentConfig)
+ return ((PersistentConfig)
config).origConfigFileContents.get(prefix + SimpleFieldSet.MULTI_LEVEL_CHAR +
name);
+ else return null;
+ }
+
}
Added: trunk/freenet/src/freenet/node/ConfigurablePersister.java
===================================================================
--- trunk/freenet/src/freenet/node/ConfigurablePersister.java
(rev 0)
+++ trunk/freenet/src/freenet/node/ConfigurablePersister.java 2007-03-22
20:37:23 UTC (rev 12277)
@@ -0,0 +1,74 @@
+package freenet.node;
+
+import java.io.File;
+import java.io.IOException;
+
+import freenet.config.InvalidConfigValueException;
+import freenet.config.SubConfig;
+import freenet.node.Node.NodeInitException;
+import freenet.support.api.StringCallback;
+
+public class ConfigurablePersister extends Persister {
+
+ public ConfigurablePersister(Persistable t, SubConfig nodeConfig,
String optionName,
+ String defaultFilename, int sortOrder, boolean expert,
boolean forceWrite, String shortDesc, String longDesc) throws NodeInitException
{
+ super(t);
+ nodeConfig.register(optionName, defaultFilename, sortOrder,
expert, forceWrite, shortDesc, longDesc, new StringCallback() {
+
+ public String get() {
+ return persistTarget.toString();
+ }
+
+ public void set(String val) throws
InvalidConfigValueException {
+ setThrottles(val);
+ }
+
+ });
+
+ String throttleFile = nodeConfig.getString(optionName);
+ try {
+ setThrottles(throttleFile);
+ } catch (InvalidConfigValueException e2) {
+ throw new
NodeInitException(Node.EXIT_THROTTLE_FILE_ERROR, e2.getMessage());
+ }
+
+ }
+
+ private void setThrottles(String val) throws
InvalidConfigValueException {
+ File f = new File(val);
+ File tmp = new File(val+".tmp");
+ while(true) {
+ if(f.exists()) {
+ if(!(f.canRead() && f.canWrite()))
+ throw new
InvalidConfigValueException("File exists and cannot read/write it");
+ break;
+ } else {
+ try {
+ f.createNewFile();
+ } catch (IOException e) {
+ throw new
InvalidConfigValueException("File does not exist and cannot be created");
+ }
+ }
+ }
+ while(true) {
+ if(tmp.exists()) {
+ if(!(tmp.canRead() && tmp.canWrite()))
+ throw new
InvalidConfigValueException("File exists and cannot read/write it");
+ break;
+ } else {
+ try {
+ tmp.createNewFile();
+ } catch (IOException e) {
+ throw new
InvalidConfigValueException("File does not exist and cannot be created");
+ }
+ }
+ }
+
+ Persister tp;
+ synchronized(this) {
+ persistTarget = f;
+ persistTemp = tmp;
+ }
+ }
+
+}
Modified: trunk/freenet/src/freenet/node/InsertHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/InsertHandler.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/InsertHandler.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -338,8 +338,8 @@
totalReceived += sender.getTotalReceivedBytes();
}
if(logMINOR) Logger.minor(this, "Remote CHK insert cost
"+totalSent+ '/' +totalReceived+" bytes ("+code+ ')');
- node.remoteChkInsertBytesSentAverage.report(totalSent);
- node.remoteChkInsertBytesReceivedAverage.report(totalReceived);
+
node.nodeStats.remoteChkInsertBytesSentAverage.report(totalSent);
+
node.nodeStats.remoteChkInsertBytesReceivedAverage.report(totalReceived);
}
}
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2007-03-22 19:16:22 UTC (rev
12276)
+++ trunk/freenet/src/freenet/node/Node.java 2007-03-22 20:37:23 UTC (rev
12277)
@@ -172,6 +172,9 @@
}
}
+ /** Stats */
+ public final NodeStats nodeStats;
+
/** Config object for the whole node. */
public final PersistentConfig config;
@@ -188,12 +191,6 @@
// Disabled to prevent long pauses every 30 seconds.
static int aggressiveGCModificator = -1 /*250*/;
- /** Minimum free heap memory bytes required to accept a request
(perhaps fewer OOMs this way) */
- public static final long MIN_FREE_HEAP_BYTES_FOR_ROUTING_SUCCESS = 3L *
1024 * 1024; // 3 MiB
-
- /** Minimum free heap memory percentage required to accept a request
(perhaps fewer OOMs this way) */
- public static final double MIN_FREE_HEAP_PERCENT_FOR_ROUTING_SUCCESS =
0.01; // 1%
-
/** If true, local requests and inserts aren't cached.
* This opens up a glaring vulnerability; connected nodes
* can then probe the store, and if the node doesn't have the
@@ -232,31 +229,7 @@
public static final int RANDOMIZED_BURSTING_HANDSHAKE_BURST_SIZE = 3;
// If we don't receive any packets at all in this period, from any
node, tell the user
public static final long ALARM_TIME = 60*1000;
- /** Sub-max ping time. If ping is greater than this, we reject some
requests. */
- public static final long SUB_MAX_PING_TIME = 700;
- /** Maximum overall average ping time. If ping is greater than this,
- * we reject all requests. */
- public static final long MAX_PING_TIME = 1500;
- /** Maximum throttled packet delay. If the throttled packet delay is
greater
- * than this, reject all packets. */
- public static final long MAX_THROTTLE_DELAY = 3000;
- /** If the throttled packet delay is less than this, reject no packets;
if it's
- * between the two, reject some packets. */
- public static final long SUB_MAX_THROTTLE_DELAY = 2000;
- /** How high can bwlimitDelayTime be before we alert (in milliseconds)*/
- public static final long MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD =
MAX_THROTTLE_DELAY*2;
- /** How high can nodeAveragePingTime be before we alert (in
milliseconds)*/
- public static final long MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD =
MAX_PING_TIME*2;
- /** How long we're over the bwlimitDelayTime threshold before we alert
(in milliseconds)*/
- public static final long MAX_BWLIMIT_DELAY_TIME_ALERT_DELAY =
10*60*1000; // 10 minutes
- /** How long we're over the nodeAveragePingTime threshold before we
alert (in milliseconds)*/
- public static final long MAX_NODE_AVERAGE_PING_TIME_ALERT_DELAY =
10*60*1000; // 10 minutes
- /** Accept one request every 10 seconds regardless, to ensure we update
the
- * block send time.
- */
- public static final int MAX_INTERREQUEST_TIME = 10*1000;
-
// 900ms
static final int MIN_INTERVAL_BETWEEN_INCOMING_SWAP_REQUESTS = 900;
public static final int SYMMETRIC_KEY_LENGTH = 32; // 256 bits - note
that this isn't used everywhere to determine it
@@ -323,8 +296,7 @@
private DSAPrivateKey myPrivKey;
/** My public key */
private DSAPublicKey myPubKey;
- /** Memory Checker thread */
- private final Thread myMemoryChecker;
+
/** My ARK SSK private key */
InsertableClientSSK myARK;
/** My ARK sequence number */
@@ -336,43 +308,16 @@
long myOldARKNumber;
/** FetchContext for ARKs */
public final FetchContext arkFetcherContext;
- /** Next time to log the PeerNode status summary */
- private long nextPeerNodeStatusLogTime = -1;
- /** PeerNode status summary log interval (milliseconds) */
- private static final long peerNodeStatusLogInterval = 5000;
- /** PeerNode statuses, by status */
- private final HashMap peerNodeStatuses;
- /** PeerNode routing backoff reasons, by reason */
- private final HashMap peerNodeRoutingBackoffReasons;
- /** Next time to update oldestNeverConnectedPeerAge */
- private long nextOldestNeverConnectedPeerAgeUpdateTime = -1;
- /** oldestNeverConnectedPeerAge update interval (milliseconds) */
- private static final long oldestNeverConnectedPeerAgeUpdateInterval =
5000;
- /** age of oldest never connected peer (milliseconds) */
- private long oldestNeverConnectedPeerAge;
- /** Next time to update PeerManagerUserAlert stats */
- private long nextPeerManagerUserAlertStatsUpdateTime = -1;
- /** PeerManagerUserAlert stats update interval (milliseconds) */
- private static final long peerManagerUserAlertStatsUpdateInterval =
1000; // 1 second
- /** first time bwlimitDelay was over PeerManagerUserAlert threshold */
- private long firstBwlimitDelayTimeThresholdBreak ;
- /** first time nodeAveragePing was over PeerManagerUserAlert threshold
*/
- private long firstNodeAveragePingTimeThresholdBreak;
- /** bwlimitDelay PeerManagerUserAlert should happen if true */
- public boolean bwlimitDelayAlertRelevant;
- /** nodeAveragePing PeerManagerUserAlert should happen if true */
- public boolean nodeAveragePingAlertRelevant;
- /** Average proportion of requests rejected immediately due to overload
*/
- public final TimeDecayingRunningAverage pInstantRejectIncoming;
+
/** IP detector */
public final NodeIPDetector ipDetector;
/** For debugging/testing, set this to true to stop the
- * probabilistic decrement at the edges of the HTLs.
- */
+ * probabilistic decrement at the edges of the HTLs. */
boolean disableProbabilisticHTLs;
/** If true, disable all hang-check functionality */
public boolean disableHangCheckers;
+ /** HashSet of currently running request UIDs */
private final HashSet runningUIDs;
byte[] myIdentity; // FIXME: simple identity block; should be unique
@@ -388,27 +333,26 @@
private String mySignedReference = null;
private String myName;
final LocationManager lm;
- final PeerManager peers; // my peers
+ /** My peers */
+ public final PeerManager peers;
/** Directory to put node, peers, etc into */
final File nodeDir;
/** Directory to put extra peer data into */
final File extraPeerDataDir;
- public final RandomSource random; // strong RNG
+ /** Strong RNG */
+ public final RandomSource random;
final UdpSocketManager usm;
final FNPPacketMangler packetMangler;
final DNSRequester dnsr;
public final PacketSender ps;
final NodeDispatcher dispatcher;
- final NodePinger nodePinger;
static final int MAX_MEMORY_CACHED_PUBKEYS = 1000;
final LRUHashtable cachedPubKeys;
final boolean testnetEnabled;
final TestnetHandler testnetHandler;
final StaticSwapRequestInterval swapInterval;
public final DoubleTokenBucket outputThrottle;
- final TokenBucket requestOutputThrottle;
- final TokenBucket requestInputThrottle;
- private boolean inputLimitDefault;
+ boolean inputLimitDefault;
public static final short DEFAULT_MAX_HTL = (short)10;
public static final int DEFAULT_SWAP_INTERVAL = 2000;
private short maxHTL;
@@ -439,16 +383,6 @@
public static final int EXIT_RESTART_FAILED = 24;
public static final int EXIT_TEST_ERROR = 25;
- public static final int PEER_NODE_STATUS_CONNECTED = 1;
- public static final int PEER_NODE_STATUS_ROUTING_BACKED_OFF = 2;
- public static final int PEER_NODE_STATUS_TOO_NEW = 3;
- public static final int PEER_NODE_STATUS_TOO_OLD = 4;
- public static final int PEER_NODE_STATUS_DISCONNECTED = 5;
- public static final int PEER_NODE_STATUS_NEVER_CONNECTED = 6;
- public static final int PEER_NODE_STATUS_DISABLED = 7;
- public static final int PEER_NODE_STATUS_BURSTING = 8;
- public static final int PEER_NODE_STATUS_LISTENING = 9;
- public static final int PEER_NODE_STATUS_LISTEN_ONLY = 10;
public static final int N2N_MESSAGE_TYPE_FPROXY_USERALERT = 1;
public static final int N2N_TEXT_MESSAGE_TYPE_USERALERT =
N2N_MESSAGE_TYPE_FPROXY_USERALERT; // **FIXME** For backwards-compatibility,
remove when removing DMT.nodeToNodeTextMessage
public static final int EXTRA_PEER_DATA_TYPE_N2NTM = 1;
@@ -461,44 +395,7 @@
public final NodeClientCore clientCore;
final String bindto;
- /** Average delay caused by throttling for sending a packet */
- final TimeDecayingRunningAverage throttledPacketSendAverage;
- // Stats
- final TimeDecayingRunningAverage remoteChkFetchBytesSentAverage;
- final TimeDecayingRunningAverage remoteSskFetchBytesSentAverage;
- final TimeDecayingRunningAverage remoteChkInsertBytesSentAverage;
- final TimeDecayingRunningAverage remoteSskInsertBytesSentAverage;
- final TimeDecayingRunningAverage remoteChkFetchBytesReceivedAverage;
- final TimeDecayingRunningAverage remoteSskFetchBytesReceivedAverage;
- final TimeDecayingRunningAverage remoteChkInsertBytesReceivedAverage;
- final TimeDecayingRunningAverage remoteSskInsertBytesReceivedAverage;
- final TimeDecayingRunningAverage localChkFetchBytesSentAverage;
- final TimeDecayingRunningAverage localSskFetchBytesSentAverage;
- final TimeDecayingRunningAverage localChkInsertBytesSentAverage;
- final TimeDecayingRunningAverage localSskInsertBytesSentAverage;
- final TimeDecayingRunningAverage localChkFetchBytesReceivedAverage;
- final TimeDecayingRunningAverage localSskFetchBytesReceivedAverage;
- final TimeDecayingRunningAverage localChkInsertBytesReceivedAverage;
- final TimeDecayingRunningAverage localSskInsertBytesReceivedAverage;
- File persistTarget;
- File persistTemp;
- private long previous_input_stat;
- private long previous_output_stat;
- private long previous_io_stat_time;
- private long last_input_stat;
- private long last_output_stat;
- private long last_io_stat_time;
- private final Object ioStatSync = new Object();
- /** Next time to update the node I/O stats */
- private long nextNodeIOStatsUpdateTime = -1;
- /** Node I/O stats update interval (milliseconds) */
- private static final long nodeIOStatsUpdateInterval = 2000;
- /** Next time to update routableConnectionStats */
- private long nextRoutableConnectionStatsUpdateTime = -1;
- /** routableConnectionStats update interval (milliseconds) */
- private static final long routableConnectionStatsUpdateInterval = 7 *
1000; // 7 seconds
-
// The version we were before we restarted.
public int lastVersion;
@@ -525,15 +422,6 @@
// Debugging stuff
private static final boolean USE_RAM_PUBKEYS_CACHE = true;
- // 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);
- protected final ThrottlePersister throttlePersister;
-
- // ThreadCounting stuffs
- private final ThreadGroup rootThreadGroup;
- private int threadLimit;
-
/**
* Read all storable settings (identity etc) from the node file.
* @param filename The name of the file to read from.
@@ -793,7 +681,6 @@
String tmp = "Initializing Node using freenet Build
#"+Version.buildNumber()+" r"+Version.cvsRevision+" and freenet-ext Build
#"+NodeStarter.extBuildNumber+" r"+NodeStarter.extRevisionNumber+" with
"+System.getProperty("java.vm.vendor")+" JVM version
"+System.getProperty("java.vm.version")+" running on
"+System.getProperty("os.arch")+' '+System.getProperty("os.name")+'
'+System.getProperty("os.version");
Logger.normal(this, tmp);
System.out.println(tmp);
- pInstantRejectIncoming = new TimeDecayingRunningAverage(0,
60000, 0.0, 1.0);
nodeStarter=ns;
if(logConfigHandler != lc)
logConfigHandler=lc;
@@ -805,10 +692,6 @@
cachedPubKeys = new LRUHashtable();
lm = new LocationManager(random);
- ThreadGroup tg = Thread.currentThread().getThreadGroup();
- while(tg.getParent() != null) tg = tg.getParent();
- this.rootThreadGroup = tg;
-
try {
localhostAddress = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e3) {
@@ -819,14 +702,10 @@
requestSenders = new HashMap();
transferringRequestSenders = new HashMap();
insertSenders = new HashMap();
- peerNodeStatuses = new HashMap();
- peerNodeRoutingBackoffReasons = new HashMap();
runningUIDs = new HashSet();
dnsr = new DNSRequester(this);
ps = new PacketSender(this);
bootID = random.nextLong();
- throttledPacketSendAverage =
- new TimeDecayingRunningAverage(1, 10*60*1000 /* should
be significantly longer than a typical transfer */, 0, Long.MAX_VALUE);
buildOldAgeUserAlert = new BuildOldAgeUserAlert();
@@ -882,12 +761,6 @@
aggressiveGCModificator = nodeConfig.getInt("aggressiveGC");
- //Memory Checking thread
- // TODO: proper config. callbacks : maybe we shoudln't start
the thread at all if it's not worthy
- this.myMemoryChecker = new Thread(new MemoryChecker(), "Memory
checker");
- this.myMemoryChecker.setPriority(Thread.MAX_PRIORITY);
- this.myMemoryChecker.setDaemon(true);
-
// FIXME maybe these configs should actually be under a node.ip
subconfig?
ipDetector = new NodeIPDetector(this);
sortOrder = ipDetector.registerConfigs(nodeConfig, sortOrder);
@@ -977,13 +850,6 @@
Logger.normal(Node.class, "Creating node...");
- previous_input_stat = 0;
- previous_output_stat = 0;
- previous_io_stat_time = 1;
- last_input_stat = 0;
- last_output_stat = 0;
- last_io_stat_time = 3;
-
// Bandwidth limit
nodeConfig.register("outputBandwidthLimit", "15K", sortOrder++,
false, true,
@@ -996,27 +862,20 @@
public void set(int obwLimit) throws
InvalidConfigValueException {
if(obwLimit <= 0) throw new
InvalidConfigValueException("Bandwidth limit must be positive");
outputThrottle.changeNanosAndBucketSizes((1000L * 1000L * 1000L) / obwLimit,
obwLimit/2, (obwLimit * 2) / 5);
- obwLimit = (obwLimit * 4) / 5;
// fudge factor; take into account non-request activity
-
requestOutputThrottle.changeNanosAndBucketSize((1000L*1000L*1000L) / obwLimit,
Math.max(obwLimit*60, 32768*20));
- if(inputLimitDefault) {
- int ibwLimit = obwLimit
* 4;
-
requestInputThrottle.changeNanosAndBucketSize((1000L*1000L*1000L) / ibwLimit,
Math.max(ibwLimit*60, 32768*20));
- }
+
nodeStats.setOutputLimit(obwLimit);
}
});
int obwLimit = nodeConfig.getInt("outputBandwidthLimit");
outputThrottle = new DoubleTokenBucket(obwLimit/2,
(1000L*1000L*1000L) / obwLimit, obwLimit, (obwLimit * 2) / 5);
obwLimit = (obwLimit * 4) / 5; // fudge factor; take into
account non-request activity
- requestOutputThrottle =
- new TokenBucket(Math.max(obwLimit*60, 32768*20),
(1000L*1000L*1000L) / obwLimit, 0);
nodeConfig.register("inputBandwidthLimit", "-1", sortOrder++,
false, true,
"Input bandwidth limit (bytes per second)",
"Input bandwidth limit (bytes/sec); the node will try not to exceed this; -1 =
4x set outputBandwidthLimit",
new IntCallback() {
public int get() {
if(inputLimitDefault) return -1;
- return (((int) ((1000L * 1000L
* 1000L) / requestInputThrottle.getNanosPerTick())) * 5) / 4;
+ return
nodeStats.getInputLimit();
}
public void set(int ibwLimit) throws
InvalidConfigValueException {
if(ibwLimit == -1) {
@@ -1027,7 +886,7 @@
ibwLimit = ibwLimit * 4
/ 5; // fudge factor; take into account non-request activity
}
if(ibwLimit <= 0) throw new
InvalidConfigValueException("Bandwidth limit must be positive or -1");
-
requestInputThrottle.changeNanosAndBucketSize((1000L*1000L*1000L) / ibwLimit,
Math.max(ibwLimit*60, 32768*20));
+
nodeStats.setInputLimit(ibwLimit);
}
});
@@ -1038,28 +897,8 @@
} else {
ibwLimit = ibwLimit * 4 / 5;
}
- requestInputThrottle =
- new TokenBucket(Math.max(ibwLimit*60, 32768*20),
(1000L*1000L*1000L) / ibwLimit, 0);
- nodeConfig.register("threadLimit", 300, sortOrder++, true,
true, "Thread limit", "The node will try to limit its thread usage to the
specified value, refusing new requests",
- new IntCallback() {
- public int get() {
- return threadLimit;
- }
- public void set(int val) throws
InvalidConfigValueException {
- if(val == get()) return;
- if(val < 250)
- throw new
InvalidConfigValueException("This value is to low for that setting, increase
it!");
- threadLimit = val;
- }
- });
-
-
- threadLimit = nodeConfig.getInt("threadLimit");
-
- // FIXME add an averaging/long-term/soft bandwidth limit. (bug
76)
-
// SwapRequestInterval
nodeConfig.register("swapRequestSendInterval",
DEFAULT_SWAP_INTERVAL, sortOrder++, true, false,
@@ -1157,7 +996,6 @@
peers = new PeerManager(this, new File(nodeDir,
"peers-"+portNumber).getPath());
peers.writePeers();
peers.updatePMUserAlert();
- nodePinger = new NodePinger(this);
usm.setDispatcher(dispatcher=new NodeDispatcher(this));
usm.setLowLevelFilter(packetMangler = new
FNPPacketMangler(this));
@@ -1437,62 +1275,25 @@
throw new NodeInitException(EXIT_STORE_OTHER, msg);
}
- nodeConfig.register("throttleFile", "throttle.dat",
sortOrder++, true, false, "File to store the persistent throttle data to",
"File to store the persistent throttle data to", new StringCallback() {
-
- public String get() {
- return persistTarget.toString();
- }
-
- public void set(String val) throws
InvalidConfigValueException {
- setThrottles(val);
- }
-
- });
-
- String throttleFile = nodeConfig.getString("throttleFile");
- try {
- setThrottles(throttleFile);
- } catch (InvalidConfigValueException e2) {
- throw new NodeInitException(EXIT_THROTTLE_FILE_ERROR,
e2.getMessage());
- }
-
- throttlePersister = new ThrottlePersister();
-
- SimpleFieldSet throttleFS = null;
- try {
- throttleFS = SimpleFieldSet.readFrom(persistTarget,
false, true);
- } catch (IOException e) {
+ // FIXME back compatibility
+ SimpleFieldSet oldThrottleFS = null;
+ File oldThrottle = new File("throttle.dat");
+ String oldThrottleName =
nodeConfig.getRawOption("throttleFile");
+ if(oldThrottleName != null)
+ oldThrottle = new File(oldThrottleName);
+ if(oldThrottle.exists() && (!new
File("node-throttle.dat").exists()) && lastVersion < 1021) {
+ // Migrate from old throttle file to new node- and
client- throttle files
try {
- throttleFS =
SimpleFieldSet.readFrom(persistTemp, false, true);
- } catch (FileNotFoundException e1) {
+ oldThrottleFS = SimpleFieldSet.readFrom(new
File("throttle.dat"), false, true);
+ } catch (IOException e) {
// Ignore
- } catch (IOException e1) {
- Logger.error(this, "Could not read
"+persistTarget+" ("+e+") and could not read "+persistTemp+" either ("+e1+ ')');
}
+ oldThrottle.delete();
}
-
- 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"));
-
- 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"));
+ nodeStats = new NodeStats(this, sortOrder, nodeConfig,
oldThrottleFS, ibwLimit, ibwLimit);
- clientCore = new NodeClientCore(this, config, nodeConfig,
nodeDir, portNumber, sortOrder, throttleFS == null ? null :
throttleFS.subset("RequestStarters"));
+ clientCore = new NodeClientCore(this, config, nodeConfig,
nodeDir, portNumber, sortOrder, oldThrottleFS == null ? null :
oldThrottleFS.subset("RequestStarters"));
nodeConfig.register("disableHangCheckers", false, sortOrder++,
true, false, "Disable all hang checkers", "Disable all hang checkers/watchdog
functions. Set this if you are profiling Fred.", new BooleanCallback() {
@@ -1533,46 +1334,6 @@
System.out.println("Node constructor completed");
}
- private void setThrottles(String val) throws
InvalidConfigValueException {
- File f = new File(val);
- File tmp = new File(val+".tmp");
- while(true) {
- if(f.exists()) {
- if(!(f.canRead() && f.canWrite()))
- throw new
InvalidConfigValueException("File exists and cannot read/write it");
- break;
- } else {
- try {
- f.createNewFile();
- } catch (IOException e) {
- throw new
InvalidConfigValueException("File does not exist and cannot be created");
- }
- }
- }
- while(true) {
- if(tmp.exists()) {
- if(!(tmp.canRead() && tmp.canWrite()))
- throw new
InvalidConfigValueException("File exists and cannot read/write it");
- break;
- } else {
- try {
- tmp.createNewFile();
- } catch (IOException e) {
- throw new
InvalidConfigValueException("File does not exist and cannot be created");
- }
- }
- }
-
- ThrottlePersister tp;
- synchronized(Node.this) {
- persistTarget = f;
- persistTemp = tmp;
- tp = throttlePersister;
- }
- if(tp != null)
- tp.interrupt();
- }
-
static final String ERROR_SUN_NPTL =
"WARNING: Your system appears to be running a Sun JVM with
NPTL. " +
"This has been known to cause the node to freeze up due to the
JVM losing a lock. " +
@@ -1587,11 +1348,9 @@
if(!noSwaps)
lm.startSender(this, this.swapInterval);
- nodePinger.start();
dnsr.start();
- ps.start();
+ ps.start(nodeStats);
usm.start(disableHangCheckers);
- myMemoryChecker.start();
peers.start();
if(isUsingWrapper()) {
@@ -1628,6 +1387,8 @@
checkForEvilJVMBug();
+ this.nodeStats.start();
+
// TODO: implement a "required" version if needed
if(!nodeUpdater.isEnabled() &&
(NodeStarter.RECOMMENDED_EXT_BUILD_NUMBER > NodeStarter.extBuildNumber))
clientCore.alerts.register(new ExtOldAgeUserAlert());
@@ -1647,9 +1408,6 @@
// Process any data in the extra peer data directory
peers.readExtraPeerData();
- Thread t = new Thread(throttlePersister, "Throttle data
persister thread");
- t.setDaemon(true);
- t.start();
Logger.normal(this, "Started node");
hasStarted = true;
@@ -1824,139 +1582,6 @@
}
- private long lastAcceptedRequest = -1;
-
- private long lastCheckedUncontended = -1;
-
- static final int ESTIMATED_SIZE_OF_ONE_THROTTLED_PACKET =
- 1024 + DMT.packetTransmitSize(1024, 32)
- + FNPPacketMangler.HEADERS_LENGTH_ONE_MESSAGE;
-
- /* return reject reason as string if should reject, otherwise return
null */
- public String shouldRejectRequest(boolean canAcceptAnyway, boolean
isInsert, boolean isSSK) {
- if(logMINOR) dumpByteCostAverages();
-
- if(threadLimit < getActiveThreadCount())
- return "Accepting the request would mean going above
the maximum number of allowed threads";
-
- double bwlimitDelayTime =
throttledPacketSendAverage.currentValue();
-
- // If no recent reports, no packets have been sent; correct the
average downwards.
- long now = System.currentTimeMillis();
- boolean checkUncontended = false;
- synchronized(this) {
- if(now - lastCheckedUncontended > 1000) {
- checkUncontended = true;
- lastCheckedUncontended = now;
- }
- }
- if(checkUncontended &&
throttledPacketSendAverage.lastReportTime() < now - 5000) { // if last report
more than 5 seconds ago
- // shouldn't take long
-
outputThrottle.blockingGrab(ESTIMATED_SIZE_OF_ONE_THROTTLED_PACKET);
-
outputThrottle.recycle(ESTIMATED_SIZE_OF_ONE_THROTTLED_PACKET);
- long after = System.currentTimeMillis();
- // Report time it takes to grab the bytes.
- throttledPacketSendAverage.report(after - now);
- now = after;
- // will have changed, use new value
- synchronized(this) {
- bwlimitDelayTime =
throttledPacketSendAverage.currentValue();
- }
- }
-
- double pingTime = nodePinger.averagePingTime();
- synchronized(this) {
- // Round trip time
- if(pingTime > MAX_PING_TIME) {
- if((now - lastAcceptedRequest >
MAX_INTERREQUEST_TIME) && canAcceptAnyway) {
- if(logMINOR) Logger.minor(this,
"Accepting request anyway (take one every 10 secs to keep bwlimitDelayTime
updated)");
- } else {
- pInstantRejectIncoming.report(1.0);
- return ">MAX_PING_TIME
("+TimeUtil.formatTime((long)pingTime, 2, true)+ ')';
- }
- } else if(pingTime > SUB_MAX_PING_TIME) {
- double x = ((double)(pingTime -
SUB_MAX_PING_TIME)) / (MAX_PING_TIME - SUB_MAX_PING_TIME);
- if(random.nextDouble() < x) {
- pInstantRejectIncoming.report(1.0);
- return ">SUB_MAX_PING_TIME
("+TimeUtil.formatTime((long)pingTime, 2, true)+ ')';
- }
- }
-
- // Bandwidth limited packets
- if(bwlimitDelayTime > MAX_THROTTLE_DELAY) {
- if((now - lastAcceptedRequest >
MAX_INTERREQUEST_TIME) && canAcceptAnyway) {
- if(logMINOR) Logger.minor(this,
"Accepting request anyway (take one every 10 secs to keep bwlimitDelayTime
updated)");
- } else {
- pInstantRejectIncoming.report(1.0);
- return ">MAX_THROTTLE_DELAY
("+TimeUtil.formatTime((long)bwlimitDelayTime, 2, true)+ ')';
- }
- } else if(bwlimitDelayTime > SUB_MAX_THROTTLE_DELAY) {
- double x = ((double)(bwlimitDelayTime -
SUB_MAX_THROTTLE_DELAY)) / (MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
- if(random.nextDouble() < x) {
- pInstantRejectIncoming.report(1.0);
- return ">SUB_MAX_THROTTLE_DELAY
("+TimeUtil.formatTime((long)bwlimitDelayTime, 2, true)+ ')';
- }
- }
-
- }
-
- // Do we have the bandwidth?
- double expected =
- (isInsert ? (isSSK ?
this.remoteSskInsertBytesSentAverage : this.remoteChkInsertBytesSentAverage)
- : (isSSK ?
this.remoteSskFetchBytesSentAverage :
this.remoteChkFetchBytesSentAverage)).currentValue();
- int expectedSent = (int)Math.max(expected, 0);
- if(!requestOutputThrottle.instantGrab(expectedSent)) {
- pInstantRejectIncoming.report(1.0);
- return "Insufficient output bandwidth";
- }
- expected =
- (isInsert ? (isSSK ?
this.remoteSskInsertBytesReceivedAverage :
this.remoteChkInsertBytesReceivedAverage)
- : (isSSK ?
this.remoteSskFetchBytesReceivedAverage :
this.remoteChkFetchBytesReceivedAverage)).currentValue();
- int expectedReceived = (int)Math.max(expected, 0);
- if(!requestInputThrottle.instantGrab(expectedReceived)) {
- requestOutputThrottle.recycle(expectedSent);
- pInstantRejectIncoming.report(1.0);
- return "Insufficient input bandwidth";
- }
-
- Runtime r = Runtime.getRuntime();
- long maxHeapMemory = r.maxMemory();
- long freeHeapMemory = r.freeMemory();
- if(freeHeapMemory < MIN_FREE_HEAP_BYTES_FOR_ROUTING_SUCCESS) {
- pInstantRejectIncoming.report(1.0);
- return "<MIN_FREE_HEAP_BYTES_FOR_ROUTING_SUCCESS
("+SizeUtil.formatSize(freeHeapMemory, false)+" of
"+SizeUtil.formatSize(maxHeapMemory, false)+')';
- }
- double percentFreeHeapMemoryOfMax = ((double) freeHeapMemory) /
((double) maxHeapMemory);
- if(percentFreeHeapMemoryOfMax <
MIN_FREE_HEAP_PERCENT_FOR_ROUTING_SUCCESS) {
- pInstantRejectIncoming.report(1.0);
- DecimalFormat fix3p1pct = new DecimalFormat("##0.0%");
- return "<MIN_FREE_HEAP_PERCENT_FOR_ROUTING_SUCCESS
("+SizeUtil.formatSize(freeHeapMemory, false)+" of
"+SizeUtil.formatSize(maxHeapMemory, false)+"
("+fix3p1pct.format(percentFreeHeapMemoryOfMax)+"))";
- }
-
- synchronized(this) {
- if(logMINOR) Logger.minor(this, "Accepting request?");
- lastAcceptedRequest = now;
- }
-
- pInstantRejectIncoming.report(0.0);
-
- // Accept
- return null;
- }
-
- private void dumpByteCostAverages() {
- Logger.minor(this, "Byte cost averages: REMOTE:"+
- " CHK insert
"+remoteChkInsertBytesSentAverage.currentValue()+ '/'
+remoteChkInsertBytesReceivedAverage.currentValue()+
- " SSK insert
"+remoteSskInsertBytesSentAverage.currentValue()+ '/'
+remoteSskInsertBytesReceivedAverage.currentValue()+
- " CHK fetch
"+remoteChkFetchBytesSentAverage.currentValue()+ '/'
+remoteChkFetchBytesReceivedAverage.currentValue()+
- " SSK fetch
"+remoteSskFetchBytesSentAverage.currentValue()+ '/'
+remoteSskFetchBytesReceivedAverage.currentValue());
- Logger.minor(this, "Byte cost averages: LOCAL"+
- " CHK insert
"+localChkInsertBytesSentAverage.currentValue()+ '/'
+localChkInsertBytesReceivedAverage.currentValue()+
- " SSK insert
"+localSskInsertBytesSentAverage.currentValue()+ '/'
+localSskInsertBytesReceivedAverage.currentValue()+
- " CHK fetch
"+localChkFetchBytesSentAverage.currentValue()+ '/'
+localChkFetchBytesReceivedAverage.currentValue()+
- " SSK fetch
"+localSskFetchBytesSentAverage.currentValue()+ '/'
+localSskFetchBytesReceivedAverage.currentValue());
- }
-
public SimpleFieldSet exportPrivateFieldSet() {
SimpleFieldSet fs = exportPublicFieldSet(false);
fs.put("dsaPrivKey", myPrivKey.asFieldSet());
@@ -2041,215 +1666,7 @@
* Export volatile data about the node as a SimpleFieldSet
*/
public SimpleFieldSet exportVolatileFieldSet() {
- SimpleFieldSet fs = new SimpleFieldSet(true);
- long now = System.currentTimeMillis();
- fs.put("isUsingWrapper", isUsingWrapper());
- long nodeUptimeSeconds = 0;
- synchronized(this) {
- fs.put("startupTime", startupTime);
- nodeUptimeSeconds = (now - startupTime) / 1000;
- fs.put("uptimeSeconds", nodeUptimeSeconds);
- }
- fs.put("averagePingTime", getNodeAveragePingTime());
- fs.put("bwlimitDelayTime", getBwlimitDelayTime());
- fs.put("networkSizeEstimateSession",
getNetworkSizeEstimate(-1));
- int networkSizeEstimate24hourRecent =
getNetworkSizeEstimate(now - (24*60*60*1000)); // 24 hours
- fs.put("networkSizeEstimate24hourRecent",
networkSizeEstimate24hourRecent);
- int networkSizeEstimate48hourRecent =
getNetworkSizeEstimate(now - (48*60*60*1000)); // 48 hours
- fs.put("networkSizeEstimate48hourRecent",
networkSizeEstimate48hourRecent);
- fs.put("routingMissDistance",
routingMissDistance.currentValue());
- fs.put("backedOffPercent", backedOffPercent.currentValue());
- fs.put("pInstantReject", pRejectIncomingInstantly());
- fs.put("unclaimedFIFOSize", usm.getUnclaimedFIFOSize());
-
- /* gather connection statistics */
- PeerNodeStatus[] peerNodeStatuses = getPeerNodeStatuses();
- Arrays.sort(peerNodeStatuses, new Comparator() {
- public int compare(Object first, Object second) {
- PeerNodeStatus firstNode = (PeerNodeStatus)
first;
- PeerNodeStatus secondNode = (PeerNodeStatus)
second;
- int statusDifference =
firstNode.getStatusValue() - secondNode.getStatusValue();
- if (statusDifference != 0) {
- return statusDifference;
- }
- return
firstNode.getName().compareToIgnoreCase(secondNode.getName());
- }
- });
-
- int numberOfConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_CONNECTED);
- int numberOfRoutingBackedOff =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
- int numberOfTooNew =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_TOO_NEW);
- int numberOfTooOld =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_TOO_OLD);
- int numberOfDisconnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_DISCONNECTED);
- int numberOfNeverConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_NEVER_CONNECTED);
- int numberOfDisabled =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_DISABLED);
- int numberOfBursting =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_BURSTING);
- int numberOfListening =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_LISTENING);
- int numberOfListenOnly =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
Node.PEER_NODE_STATUS_LISTEN_ONLY);
-
- int numberOfSimpleConnected = numberOfConnected +
numberOfRoutingBackedOff;
- int numberOfNotConnected = numberOfTooNew + numberOfTooOld +
numberOfDisconnected + numberOfNeverConnected + numberOfDisabled +
numberOfBursting + numberOfListening + numberOfListenOnly;
-
- fs.put("numberOfConnected", numberOfConnected);
- fs.put("numberOfRoutingBackedOff", numberOfRoutingBackedOff);
- fs.put("numberOfTooNew", numberOfTooNew);
- fs.put("numberOfTooOld", numberOfTooOld);
- fs.put("numberOfDisconnected", numberOfDisconnected);
- fs.put("numberOfNeverConnected", numberOfNeverConnected);
- fs.put("numberOfDisabled", numberOfDisabled);
- fs.put("numberOfBursting", numberOfBursting);
- fs.put("numberOfListening", numberOfListening);
- fs.put("numberOfListenOnly", numberOfListenOnly);
-
- fs.put("numberOfSimpleConnected", numberOfSimpleConnected);
- fs.put("numberOfNotConnected", numberOfNotConnected);
-
- fs.put("numberOfInserts", getNumInserts());
- fs.put("numberOfRequests", getNumRequests());
- fs.put("numberOfTransferringRequests",
getNumTransferringRequests());
- fs.put("numberOfARKFetchers", getNumARKFetchers());
-
- long[] total = IOStatisticCollector.getTotalIO();
- long total_output_rate = (total[0]) / nodeUptimeSeconds;
- long total_input_rate = (total[1]) / nodeUptimeSeconds;
- long totalPayloadOutput = getTotalPayloadSent();
- long total_payload_output_rate = totalPayloadOutput /
nodeUptimeSeconds;
- int total_payload_output_percent = (int) (100 *
totalPayloadOutput / total[0]);
- fs.put("totalOutputBytes", total[0]);
- fs.put("totalOutputRate", total_output_rate);
- fs.put("totalPayloadOutputBytes", totalPayloadOutput);
- fs.put("totalPayloadOutputRate", total_payload_output_rate);
- fs.put("totalPayloadOutputPercent",
total_payload_output_percent);
- fs.put("totalInputBytes", total[1]);
- fs.put("totalInputRate", total_input_rate);
- long[] rate = getNodeIOStats();
- long delta = (rate[5] - rate[2]) / 1000;
- long recent_output_rate = (rate[3] - rate[0]) / delta;
- long recent_input_rate = (rate[4] - rate[1]) / delta;
- fs.put("recentOutputRate", recent_output_rate);
- fs.put("recentInputRate", recent_input_rate);
-
- String [] routingBackoffReasons =
getPeerNodeRoutingBackoffReasons();
- if(routingBackoffReasons.length != 0) {
- for(int i=0;i<routingBackoffReasons.length;i++) {
- fs.put("numberWithRoutingBackoffReasons." +
routingBackoffReasons[i],
getPeerNodeRoutingBackoffReasonSize(routingBackoffReasons[i]));
- }
- }
-
- double swaps = (double)getSwaps();
- double noSwaps = (double)getNoSwaps();
- double numberOfRemotePeerLocationsSeenInSwaps =
(double)getNumberOfRemotePeerLocationsSeenInSwaps();
- fs.putSingle("numberOfRemotePeerLocationsSeenInSwaps",
Double.toString(numberOfRemotePeerLocationsSeenInSwaps));
- double avgConnectedPeersPerNode = 0.0;
- if ((numberOfRemotePeerLocationsSeenInSwaps > 0.0) && ((swaps >
0.0) || (noSwaps > 0.0))) {
- avgConnectedPeersPerNode =
numberOfRemotePeerLocationsSeenInSwaps/(swaps+noSwaps);
- }
- fs.putSingle("avgConnectedPeersPerNode",
Double.toString(avgConnectedPeersPerNode));
-
- int startedSwaps = getStartedSwaps();
- int swapsRejectedAlreadyLocked =
getSwapsRejectedAlreadyLocked();
- int swapsRejectedNowhereToGo = getSwapsRejectedNowhereToGo();
- int swapsRejectedRateLimit = getSwapsRejectedRateLimit();
- int swapsRejectedLoop = getSwapsRejectedLoop();
- int swapsRejectedRecognizedID = getSwapsRejectedRecognizedID();
- double locationChangePerSession = getLocationChangeSession();
- double locationChangePerSwap = 0.0;
- double locationChangePerMinute = 0.0;
- double swapsPerMinute = 0.0;
- double noSwapsPerMinute = 0.0;
- double swapsPerNoSwaps = 0.0;
- if (swaps > 0) {
- locationChangePerSwap = locationChangePerSession/swaps;
- }
- if ((swaps > 0.0) && (nodeUptimeSeconds >= 60)) {
- locationChangePerMinute =
locationChangePerSession/(double)(nodeUptimeSeconds/60.0);
- }
- if ((swaps > 0.0) && (nodeUptimeSeconds >= 60)) {
- swapsPerMinute = swaps/(double)(nodeUptimeSeconds/60.0);
- }
- if ((noSwaps > 0.0) && (nodeUptimeSeconds >= 60)) {
- noSwapsPerMinute =
noSwaps/(double)(nodeUptimeSeconds/60.0);
- }
- if ((swaps > 0.0) && (noSwaps > 0.0)) {
- swapsPerNoSwaps = swaps/noSwaps;
- }
- fs.put("locationChangePerSession", locationChangePerSession);
- fs.put("locationChangePerSwap", locationChangePerSwap);
- fs.put("locationChangePerMinute", locationChangePerMinute);
- fs.put("swapsPerMinute", swapsPerMinute);
- fs.put("noSwapsPerMinute", noSwapsPerMinute);
- fs.put("swapsPerNoSwaps", swapsPerNoSwaps);
- fs.put("swaps", swaps);
- fs.put("noSwaps", noSwaps);
- fs.put("startedSwaps", startedSwaps);
- fs.put("swapsRejectedAlreadyLocked",
swapsRejectedAlreadyLocked);
- fs.put("swapsRejectedNowhereToGo", swapsRejectedNowhereToGo);
- fs.put("swapsRejectedRateLimit", swapsRejectedRateLimit);
- fs.put("swapsRejectedLoop", swapsRejectedLoop);
- fs.put("swapsRejectedRecognizedID", swapsRejectedRecognizedID);
-
- long fix32kb = 32 * 1024;
- long cachedKeys = getChkDatacache().keyCount();
- long cachedSize = cachedKeys * fix32kb;
- long storeKeys = getChkDatastore().keyCount();
- long storeSize = storeKeys * fix32kb;
- long overallKeys = cachedKeys + storeKeys;
- long overallSize = cachedSize + storeSize;
-
- long maxOverallKeys = getMaxTotalKeys();
- long maxOverallSize = maxOverallKeys * fix32kb;
-
- double percentOverallKeysOfMax =
(double)(overallKeys*100)/(double)maxOverallKeys;
-
- long cachedStoreHits = getChkDatacache().hits();
- long cachedStoreMisses = getChkDatacache().misses();
- long cacheAccesses = cachedStoreHits + cachedStoreMisses;
- double percentCachedStoreHitsOfAccesses =
(double)(cachedStoreHits*100) / (double)cacheAccesses;
- long storeHits = getChkDatastore().hits();
- long storeMisses = getChkDatastore().misses();
- long storeAccesses = storeHits + storeMisses;
- double percentStoreHitsOfAccesses = (double)(storeHits*100) /
(double)storeAccesses;
- long overallAccesses = storeAccesses + cacheAccesses;
- double avgStoreAccessRate =
(double)overallAccesses/(double)nodeUptimeSeconds;
-
- fs.put("cachedKeys", cachedKeys);
- fs.put("cachedSize", cachedSize);
- fs.put("storeKeys", storeKeys);
- fs.put("storeSize", storeSize);
- fs.put("overallKeys", overallKeys);
- fs.put("overallSize", overallSize);
- fs.put("maxOverallKeys", maxOverallKeys);
- fs.put("maxOverallSize", maxOverallSize);
- fs.put("percentOverallKeysOfMax", percentOverallKeysOfMax);
- fs.put("cachedStoreHits", cachedStoreHits);
- fs.put("cachedStoreMisses", cachedStoreMisses);
- fs.put("cacheAccesses", cacheAccesses);
- fs.put("percentCachedStoreHitsOfAccesses",
percentCachedStoreHitsOfAccesses);
- fs.put("storeHits", storeHits);
- fs.put("storeMisses", storeMisses);
- fs.put("storeAccesses", storeAccesses);
- fs.put("percentStoreHitsOfAccesses",
percentStoreHitsOfAccesses);
- fs.put("overallAccesses", overallAccesses);
- fs.put("avgStoreAccessRate", avgStoreAccessRate);
-
- Runtime rt = Runtime.getRuntime();
- float freeMemory = (float) rt.freeMemory();
- float totalMemory = (float) rt.totalMemory();
- float maxMemory = (float) rt.maxMemory();
-
- long usedJavaMem = (long)(totalMemory - freeMemory);
- long allocatedJavaMem = (long)totalMemory;
- long maxJavaMem = (long)maxMemory;
- int availableCpus = rt.availableProcessors();
-
- fs.put("freeJavaMemory", (long)freeMemory);
- fs.put("usedJavaMemory", usedJavaMem);
- fs.put("allocatedJavaMemory", allocatedJavaMem);
- fs.put("maximumJavaMemory", maxJavaMem);
- fs.put("availableCPUs", availableCpus);
- fs.put("runningThreadCount", getActiveThreadCount());
-
- return fs;
+ return nodeStats.exportVolatileFieldSet();
}
/**
@@ -3013,172 +2430,7 @@
return false;
}
- public double getBwlimitDelayTime() {
- return throttledPacketSendAverage.currentValue();
- }
-
- public double getNodeAveragePingTime() {
- return nodePinger.averagePingTime();
- }
-
/**
- * Add a ARKFetcher to the map
- */
- /**
- * Add a PeerNode status to the map
- */
- public void addPeerNodeStatus(int pnStatus, PeerNode peerNode) {
- Integer peerNodeStatus = new Integer(pnStatus);
- HashSet statusSet = null;
- synchronized(peerNodeStatuses) {
- if(peerNodeStatuses.containsKey(peerNodeStatus)) {
- statusSet = (HashSet)
peerNodeStatuses.get(peerNodeStatus);
- if(statusSet.contains(peerNode)) {
- Logger.error(this,
"addPeerNodeStatus(): identity '"+peerNode.getIdentityString()+"' already in
peerNodeStatuses as "+peerNode+" with status code "+peerNodeStatus);
- return;
- }
- peerNodeStatuses.remove(peerNodeStatus);
- } else {
- statusSet = new HashSet();
- }
- if(logMINOR) Logger.minor(this, "addPeerNodeStatus():
adding PeerNode for '"+peerNode.getIdentityString()+"' with status code
"+peerNodeStatus);
- statusSet.add(peerNode);
- peerNodeStatuses.put(peerNodeStatus, statusSet);
- }
- }
-
- /**
- * How many PeerNodes have a particular status?
- */
- public int getPeerNodeStatusSize(int pnStatus) {
- Integer peerNodeStatus = new Integer(pnStatus);
- HashSet statusSet = null;
- synchronized(peerNodeStatuses) {
- if(peerNodeStatuses.containsKey(peerNodeStatus)) {
- statusSet = (HashSet)
peerNodeStatuses.get(peerNodeStatus);
- } else {
- statusSet = new HashSet();
- }
- return statusSet.size();
- }
- }
-
- /**
- * Remove a PeerNode status from the map
- */
- public void removePeerNodeStatus(int pnStatus, PeerNode peerNode) {
- Integer peerNodeStatus = new Integer(pnStatus);
- HashSet statusSet = null;
- synchronized(peerNodeStatuses) {
- if(peerNodeStatuses.containsKey(peerNodeStatus)) {
- statusSet = (HashSet)
peerNodeStatuses.get(peerNodeStatus);
- if(!statusSet.contains(peerNode)) {
- Logger.error(this,
"removePeerNodeStatus(): identity '"+peerNode.getIdentityString()+"' not in
peerNodeStatuses with status code "+peerNodeStatus);
- return;
- }
- peerNodeStatuses.remove(peerNodeStatus);
- } else {
- statusSet = new HashSet();
- }
- if(logMINOR) Logger.minor(this,
"removePeerNodeStatus(): removing PeerNode for
'"+peerNode.getIdentityString()+"' with status code "+peerNodeStatus);
- if(statusSet.contains(peerNode)) {
- statusSet.remove(peerNode);
- }
- peerNodeStatuses.put(peerNodeStatus, statusSet);
- }
- }
-
- /**
- * Log the current PeerNode status summary if the timer has expired
- */
- public void maybeLogPeerNodeStatusSummary(long now) {
- if(now > nextPeerNodeStatusLogTime) {
- if((now - nextPeerNodeStatusLogTime) > (10*1000) &&
nextPeerNodeStatusLogTime > 0)
- Logger.error(this,"maybeLogPeerNodeStatusSummary() not called
for more than 10 seconds ("+(now - nextPeerNodeStatusLogTime)+"). PacketSender
getting bogged down or something?");
-
- int numberOfConnected = 0;
- int numberOfRoutingBackedOff = 0;
- int numberOfTooNew = 0;
- int numberOfTooOld = 0;
- int numberOfDisconnected = 0;
- int numberOfNeverConnected = 0;
- int numberOfDisabled = 0;
- int numberOfListenOnly = 0;
- int numberOfListening = 0;
- int numberOfBursting = 0;
-
- PeerNodeStatus[] pns = getPeerNodeStatuses();
-
- for(int i=0; i<pns.length; i++){
- switch (pns[i].getStatusValue()) {
- case PEER_NODE_STATUS_CONNECTED:
- numberOfConnected++;
- break;
- case PEER_NODE_STATUS_ROUTING_BACKED_OFF:
- numberOfRoutingBackedOff++;
- break;
- case PEER_NODE_STATUS_TOO_NEW:
- numberOfTooNew++;
- break;
- case PEER_NODE_STATUS_TOO_OLD:
- numberOfTooOld++;
- break;
- case PEER_NODE_STATUS_DISCONNECTED:
- numberOfDisconnected++;
- break;
- case PEER_NODE_STATUS_NEVER_CONNECTED:
- numberOfNeverConnected++;
- break;
- case PEER_NODE_STATUS_DISABLED:
- numberOfDisabled++;
- break;
- case PEER_NODE_STATUS_LISTEN_ONLY:
- numberOfListenOnly++;
- break;
- case PEER_NODE_STATUS_LISTENING:
- numberOfListening++;
- break;
- case PEER_NODE_STATUS_BURSTING:
- numberOfBursting++;
- break;
- default:
- Logger.error(this, "Unknown peer status value :
"+pns[i].getStatusValue());
- break;
- }
- }
- Logger.normal(this, "Connected: "+numberOfConnected+" Routing
Backed Off: "+numberOfRoutingBackedOff+" Too New: "+numberOfTooNew+" Too Old:
"+numberOfTooOld+" Disconnected: "+numberOfDisconnected+" Never Connected:
"+numberOfNeverConnected+" Disabled: "+numberOfDisabled+" Bursting:
"+numberOfBursting+" Listening: "+numberOfListening+" Listen Only:
"+numberOfListenOnly);
- nextPeerNodeStatusLogTime = now + peerNodeStatusLogInterval;
- }
- }
-
- /**
- * Update oldestNeverConnectedPeerAge if the timer has expired
- */
- public void maybeUpdateOldestNeverConnectedPeerAge(long now) {
- if(now > nextOldestNeverConnectedPeerAgeUpdateTime) {
- oldestNeverConnectedPeerAge = 0;
- if(peers != null) {
- PeerNode[] peerList = peers.myPeers;
- for(int i=0;i<peerList.length;i++) {
- PeerNode pn = peerList[i];
- if(pn.getPeerNodeStatus() ==
PEER_NODE_STATUS_NEVER_CONNECTED) {
- if((now - pn.getPeerAddedTime()) >
oldestNeverConnectedPeerAge) {
- oldestNeverConnectedPeerAge = now -
pn.getPeerAddedTime();
- }
- }
- }
- }
- if(oldestNeverConnectedPeerAge > 0 && logMINOR)
- Logger.minor(this, "Oldest never connected peer is
"+oldestNeverConnectedPeerAge+"ms old");
- nextOldestNeverConnectedPeerAgeUpdateTime = now +
oldestNeverConnectedPeerAgeUpdateInterval;
- }
- }
-
- public long getOldestNeverConnectedPeerAge() {
- return oldestNeverConnectedPeerAge;
- }
-
- /**
* Handle a received node to node message
*/
public void receivedNodeToNodeMessage(Message m) {
@@ -3295,14 +2547,6 @@
return usm;
}
- public int getNetworkSizeEstimate(long timestamp) {
- return lm.getNetworkSizeEstimate( timestamp );
- }
-
- public Object[] getKnownLocations(long timestamp) {
- return lm.getKnownLocations( timestamp );
- }
-
public int getSwaps() {
return LocationManager.swaps;
}
@@ -3335,115 +2579,6 @@
return LocationManager.swapsRejectedRecognizedID;
}
- /**
- * Add a PeerNode routing backoff reason to the map
- */
- public void addPeerNodeRoutingBackoffReason(String
peerNodeRoutingBackoffReason, PeerNode peerNode) {
- synchronized(peerNodeRoutingBackoffReasons) {
- HashSet reasonSet = null;
-
if(peerNodeRoutingBackoffReasons.containsKey(peerNodeRoutingBackoffReason)) {
- reasonSet = (HashSet)
peerNodeRoutingBackoffReasons.get(peerNodeRoutingBackoffReason);
- if(reasonSet.contains(peerNode)) {
- Logger.error(this,
"addPeerNodeRoutingBackoffReason(): identity '"+peerNode.getIdentityString()+"'
already in peerNodeRoutingBackoffReasons as "+peerNode+" with status code
"+peerNodeRoutingBackoffReason);
- return;
- }
-
peerNodeRoutingBackoffReasons.remove(peerNodeRoutingBackoffReason);
- } else {
- reasonSet = new HashSet();
- }
- if(logMINOR) Logger.minor(this,
"addPeerNodeRoutingBackoffReason(): adding PeerNode for
'"+peerNode.getIdentityString()+"' with status code
"+peerNodeRoutingBackoffReason);
- reasonSet.add(peerNode);
-
peerNodeRoutingBackoffReasons.put(peerNodeRoutingBackoffReason, reasonSet);
- }
- }
-
- /**
- * What are the currently tracked PeerNode routing backoff reasons?
- */
- public String [] getPeerNodeRoutingBackoffReasons() {
- String [] reasonStrings;
- synchronized(peerNodeRoutingBackoffReasons) {
- reasonStrings = (String [])
peerNodeRoutingBackoffReasons.keySet().toArray(new
String[peerNodeRoutingBackoffReasons.size()]);
- }
- Arrays.sort(reasonStrings);
- return reasonStrings;
- }
-
- /**
- * How many PeerNodes have a particular routing backoff reason?
- */
- public int getPeerNodeRoutingBackoffReasonSize(String
peerNodeRoutingBackoffReason) {
- HashSet reasonSet = null;
- synchronized(peerNodeRoutingBackoffReasons) {
-
if(peerNodeRoutingBackoffReasons.containsKey(peerNodeRoutingBackoffReason)) {
- reasonSet = (HashSet)
peerNodeRoutingBackoffReasons.get(peerNodeRoutingBackoffReason);
- return reasonSet.size();
- } else {
- return 0;
- }
- }
- }
-
- /**
- * Remove a PeerNode routing backoff reason from the map
- */
- public void removePeerNodeRoutingBackoffReason(String
peerNodeRoutingBackoffReason, PeerNode peerNode) {
- HashSet reasonSet = null;
- synchronized(peerNodeRoutingBackoffReasons) {
-
if(peerNodeRoutingBackoffReasons.containsKey(peerNodeRoutingBackoffReason)) {
- reasonSet = (HashSet)
peerNodeRoutingBackoffReasons.get(peerNodeRoutingBackoffReason);
- if(!reasonSet.contains(peerNode)) {
- Logger.error(this,
"removePeerNodeRoutingBackoffReason(): identity
'"+peerNode.getIdentityString()+"' not in peerNodeRoutingBackoffReasons with
status code "+peerNodeRoutingBackoffReason);
- return;
- }
-
peerNodeRoutingBackoffReasons.remove(peerNodeRoutingBackoffReason);
- } else {
- reasonSet = new HashSet();
- }
- if(logMINOR) Logger.minor(this,
"removePeerNodeRoutingBackoffReason(): removing PeerNode for
'"+peerNode.getIdentityString()+"' with status code
"+peerNodeRoutingBackoffReason);
- if(reasonSet.contains(peerNode)) {
- reasonSet.remove(peerNode);
- }
- if(reasonSet.size() > 0) {
-
peerNodeRoutingBackoffReasons.put(peerNodeRoutingBackoffReason, reasonSet);
- }
- }
- }
-
- /**
- * Update peerManagerUserAlertStats if the timer has expired
- */
- public void maybeUpdatePeerManagerUserAlertStats(long now) {
- if(now > nextPeerManagerUserAlertStatsUpdateTime) {
- if(getBwlimitDelayTime() >
MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD) {
- if(firstBwlimitDelayTimeThresholdBreak == 0) {
- firstBwlimitDelayTimeThresholdBreak =
now;
- }
- } else {
- firstBwlimitDelayTimeThresholdBreak = 0;
- }
- if((firstBwlimitDelayTimeThresholdBreak != 0) && ((now
- firstBwlimitDelayTimeThresholdBreak) >= MAX_BWLIMIT_DELAY_TIME_ALERT_DELAY)) {
- bwlimitDelayAlertRelevant = true;
- } else {
- bwlimitDelayAlertRelevant = false;
- }
- if(getNodeAveragePingTime() >
MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD) {
- if(firstNodeAveragePingTimeThresholdBreak == 0)
{
- firstNodeAveragePingTimeThresholdBreak
= now;
- }
- } else {
- firstNodeAveragePingTimeThresholdBreak = 0;
- }
- if((firstNodeAveragePingTimeThresholdBreak != 0) &&
((now - firstNodeAveragePingTimeThresholdBreak) >=
MAX_NODE_AVERAGE_PING_TIME_ALERT_DELAY)) {
- nodeAveragePingAlertRelevant = true;
- } else {
- nodeAveragePingAlertRelevant = false;
- }
- if(logMINOR && Logger.shouldLog(Logger.DEBUG, this))
Logger.debug(this, "mUPMUAS: "+now+": "+getBwlimitDelayTime()+" >?
"+MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD+" since
"+firstBwlimitDelayTimeThresholdBreak+" ("+bwlimitDelayAlertRelevant+")
"+getNodeAveragePingTime()+" >? "+MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD+"
since "+firstNodeAveragePingTimeThresholdBreak+"
("+nodeAveragePingAlertRelevant+ ')');
- nextPeerManagerUserAlertStatsUpdateTime = now +
peerManagerUserAlertStatsUpdateInterval;
- }
- }
-
public PeerNode[] getPeerNodes() {
return peers.myPeers;
}
@@ -3452,14 +2587,6 @@
return peers.connectedPeers;
}
- public PeerNodeStatus[] getPeerNodeStatuses() {
- PeerNodeStatus[] peerNodeStatuses = new
PeerNodeStatus[peers.myPeers.length];
- for (int peerIndex = 0, peerCount = peers.myPeers.length;
peerIndex < peerCount; peerIndex++) {
- peerNodeStatuses[peerIndex] =
peers.myPeers[peerIndex].getStatus();
- }
- return peerNodeStatuses;
- }
-
/**
* Return a peer of the node given its ip and port, name or identity,
as a String
*/
@@ -3490,10 +2617,6 @@
clientCore.queueRandomReinsert(block);
}
- public double pRejectIncomingInstantly() {
- return pInstantRejectIncoming.currentValue();
- }
-
public String getExtraPeerDataDir() {
return extraPeerDataDir.getPath();
}
@@ -3525,148 +2648,6 @@
// FIXME convert these kind of threads to Checkpointed's and implement
a handler
// using the PacketSender/Ticker. Would save a few threads.
- class ThrottlePersister implements Runnable {
-
- void interrupt() {
- synchronized(this) {
- notifyAll();
- }
- }
-
- public void run() {
- while(true) {
- try {
- persistThrottle();
- } catch (OutOfMemoryError e) {
- OOMHandler.handleOOM(e);
- System.err.println("Will restart
ThrottlePersister...");
- } catch (Throwable t) {
- Logger.error(this, "Caught in
ThrottlePersister: "+t, t);
- System.err.println("Caught in
ThrottlePersister: "+t);
- t.printStackTrace();
- System.err.println("Will restart
ThrottlePersister...");
- }
- try {
- synchronized(this) {
- wait(60*1000);
- }
- } catch (InterruptedException e) {
- // Maybe it's time to wake up?
- }
- }
- }
-
- }
-
- public void persistThrottle() {
- if(logMINOR) Logger.minor(this, "Trying to persist
throttles...");
- SimpleFieldSet fs = persistThrottlesToFieldSet();
- try {
- FileOutputStream fos = new
FileOutputStream(persistTemp);
- // FIXME common pattern, reuse it.
- BufferedOutputStream bos = new
BufferedOutputStream(fos);
- OutputStreamWriter osw = new OutputStreamWriter(bos,
"UTF-8");
- BufferedWriter bw = new BufferedWriter(osw);
- try {
- fs.writeTo(bw);
- } catch (IOException e) {
- try {
- fos.close();
- persistTemp.delete();
- return;
- } catch (IOException e1) {
- // Ignore
- }
- }
- try {
- bw.close();
- } catch (IOException e) {
- // Huh?
- Logger.error(this, "Caught while closing: "+e,
e);
- return;
- }
- // Try an atomic rename
- if(!persistTemp.renameTo(persistTarget)) {
- // Not supported on some systems (Windows)
- if(!persistTarget.delete()) {
- if(persistTarget.exists()) {
- Logger.error(this, "Could not
delete "+persistTarget+" - check permissions");
- }
- }
- if(!persistTemp.renameTo(persistTarget)) {
- Logger.error(this, "Could not rename
"+persistTemp+" to "+persistTarget+" - check permissions");
- }
- }
- } catch (FileNotFoundException e) {
- Logger.error(this, "Could not store throttle data to
disk: "+e, e);
- return;
- } catch (UnsupportedEncodingException e) {
- Logger.error(this, "Unsupported encoding: UTF-8 !!!!:
"+e, e);
- }
-
- }
-
- private SimpleFieldSet persistThrottlesToFieldSet() {
- SimpleFieldSet fs = new SimpleFieldSet(true);
- fs.put("RequestStarters",
clientCore.requestStarters.persistToFieldSet());
- fs.put("RemoteChkFetchBytesSentAverage",
remoteChkFetchBytesSentAverage.exportFieldSet(true));
- fs.put("RemoteSskFetchBytesSentAverage",
remoteSskFetchBytesSentAverage.exportFieldSet(true));
- fs.put("RemoteChkInsertBytesSentAverage",
remoteChkInsertBytesSentAverage.exportFieldSet(true));
- fs.put("RemoteSskInsertBytesSentAverage",
remoteSskInsertBytesSentAverage.exportFieldSet(true));
- fs.put("RemoteChkFetchBytesReceivedAverage",
remoteChkFetchBytesReceivedAverage.exportFieldSet(true));
- fs.put("RemoteSskFetchBytesReceivedAverage",
remoteSskFetchBytesReceivedAverage.exportFieldSet(true));
- fs.put("RemoteChkInsertBytesReceivedAverage",
remoteChkInsertBytesReceivedAverage.exportFieldSet(true));
- fs.put("RemoteSskInsertBytesReceivedAverage",
remoteSskInsertBytesReceivedAverage.exportFieldSet(true));
- fs.put("LocalChkFetchBytesSentAverage",
localChkFetchBytesSentAverage.exportFieldSet(true));
- fs.put("LocalSskFetchBytesSentAverage",
localSskFetchBytesSentAverage.exportFieldSet(true));
- fs.put("LocalChkInsertBytesSentAverage",
localChkInsertBytesSentAverage.exportFieldSet(true));
- fs.put("LocalSskInsertBytesSentAverage",
localSskInsertBytesSentAverage.exportFieldSet(true));
- fs.put("LocalChkFetchBytesReceivedAverage",
localChkFetchBytesReceivedAverage.exportFieldSet(true));
- fs.put("LocalSskFetchBytesReceivedAverage",
localSskFetchBytesReceivedAverage.exportFieldSet(true));
- fs.put("LocalChkInsertBytesReceivedAverage",
localChkInsertBytesReceivedAverage.exportFieldSet(true));
- fs.put("LocalSskInsertBytesReceivedAverage",
localSskInsertBytesReceivedAverage.exportFieldSet(true));
-
- // FIXME persist the rest
- return fs;
- }
-
- /**
- * Update the node-wide bandwidth I/O stats if the timer has expired
- */
- public void maybeUpdateNodeIOStats(long now) {
- if(now > nextNodeIOStatsUpdateTime) {
- long[] io_stats = IOStatisticCollector.getTotalIO();
- long outdiff;
- long indiff;
- synchronized(ioStatSync) {
- previous_output_stat = last_output_stat;
- previous_input_stat = last_input_stat;
- previous_io_stat_time = last_io_stat_time;
- last_output_stat = io_stats[ 0 ];
- last_input_stat = io_stats[ 1 ];
- last_io_stat_time = now;
- outdiff = last_output_stat -
previous_output_stat;
- indiff = last_input_stat - previous_input_stat;
- }
- if(logMINOR)
- Logger.minor(this, "Last 2 seconds: input:
"+indiff+" output: "+outdiff);
- nextNodeIOStatsUpdateTime = now +
nodeIOStatsUpdateInterval;
- }
- }
-
- public long[] getNodeIOStats() {
- long[] result = new long[6];
- synchronized(ioStatSync) {
- result[ 0 ] = previous_output_stat;
- result[ 1 ] = previous_input_stat;
- result[ 2 ] = previous_io_stat_time;
- result[ 3 ] = last_output_stat;
- result[ 4 ] = last_input_stat;
- result[ 5 ] = last_io_stat_time;
- }
- return result;
- }
-
public int getNumARKFetchers() {
PeerNode[] p = peers.myPeers;
int x = 0;
@@ -3705,30 +2686,6 @@
return myPubKey;
}
- public void waitUntilNotOverloaded(boolean isInsert) {
- while(threadLimit < getActiveThreadCount()){
- try{
- wait(5000);
- } catch (InterruptedException e) {}
- }
- }
-
- /**
- * Update hadRoutableConnectionCount/routableConnectionCheckCount on
peers if the timer has expired
- */
- public void maybeUpdatePeerNodeRoutableConnectionStats(long now) {
- if(now > nextRoutableConnectionStatsUpdateTime) {
- if(peers != null && -1 !=
nextRoutableConnectionStatsUpdateTime) {
- PeerNode[] peerList = peers.myPeers;
- for(int i=0;i<peerList.length;i++) {
- PeerNode pn = peerList[i];
- pn.checkRoutableConnectionStatus();
- }
- }
- nextRoutableConnectionStatsUpdateTime = now +
routableConnectionStatsUpdateInterval;
- }
- }
-
public Ticker getTicker() {
return ps;
}
@@ -3760,12 +2717,4 @@
System.out.println("Failed to get stats from JE
environment: " + e);
}
}
-
- public int getActiveThreadCount() {
- return rootThreadGroup.activeCount();
- }
-
- public int getThreadLimit() {
- return threadLimit;
- }
}
Modified: trunk/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeClientCore.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/NodeClientCore.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -1,6 +1,7 @@
package freenet.node;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
@@ -57,7 +58,7 @@
/**
* The connection between the node and the client layer.
*/
-public class NodeClientCore {
+public class NodeClientCore implements Persistable {
private static boolean logMINOR;
public final USKManager uskManager;
@@ -76,6 +77,7 @@
final FilenameGenerator tempFilenameGenerator;
public final BucketFactory tempBucketFactory;
final Node node;
+ final NodeStats nodeStats;
public final RandomSource random;
final File tempDir;
@@ -96,6 +98,7 @@
public boolean ignoreTooManyPathComponents;
/** If true, requests are resumed lazily i.e. startup does not block
waiting for them. */
private boolean lazyResume;
+ protected final Persister persister;
// Client stuff that needs to be configged - FIXME
static final int MAX_ARCHIVE_HANDLERS = 200; // don't take up much
RAM... FIXME
@@ -104,8 +107,9 @@
static final long MAX_ARCHIVED_FILE_SIZE = 1024*1024; // arbitrary...
FIXME
static final int MAX_CACHED_ELEMENTS = 1024; // equally arbitrary!
FIXME hopefully we can cache many of these though
- NodeClientCore(Node node, Config config, SubConfig nodeConfig, File
nodeDir, int portNumber, int sortOrder, SimpleFieldSet throttleFS) throws
NodeInitException {
+ NodeClientCore(Node node, Config config, SubConfig nodeConfig, File
nodeDir, int portNumber, int sortOrder, SimpleFieldSet oldThrottleFS) throws
NodeInitException {
this.node = node;
+ this.nodeStats = node.nodeStats;
this.random = node.random;
this.backgroundBlockEncoder = new BackgroundBlockEncoder();
Thread t = new Thread(backgroundBlockEncoder, "Background block
encoder");
@@ -117,6 +121,17 @@
this.formPassword = Base64.encode(pwdBuf);
alerts = new UserAlertManager(this);
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+
+ persister = new ConfigurablePersister(this, nodeConfig,
"clientThrottleFile", "client-throttle.dat", sortOrder++, true, false,
+ "File to store client statistics in", "File to
store client throttling statistics in (used to decide how often to send
requests)");
+
+ SimpleFieldSet throttleFS = persister.read();
+
+ if(throttleFS == null)
+ throttleFS = oldThrottleFS;
+
+ if(logMINOR) Logger.minor(this, "Read
throttleFS:\n"+throttleFS);
+
if(logMINOR) Logger.minor(this, "Serializing
RequestStarterGroup from:\n"+throttleFS);
requestStarters = new RequestStarterGroup(node, this,
portNumber, random, config, throttleFS);
@@ -333,6 +348,8 @@
}
public void start(Config config) throws NodeInitException {
+
+ persister.start();
// TMCI
try{
@@ -428,8 +445,8 @@
if(status != RequestSender.TIMED_OUT && status !=
RequestSender.GENERATED_REJECTED_OVERLOAD && status !=
RequestSender.INTERNAL_ERROR) {
if(logMINOR) Logger.minor(this, "CHK fetch cost
"+rs.getTotalSentBytes()+ '/' +rs.getTotalReceivedBytes()+" bytes ("+status+
')');
-
node.localChkFetchBytesSentAverage.report(rs.getTotalSentBytes());
-
node.localChkFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
+
nodeStats.localChkFetchBytesSentAverage.report(rs.getTotalSentBytes());
+
nodeStats.localChkFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
}
if((status == RequestSender.TIMED_OUT) ||
@@ -527,8 +544,8 @@
if(status != RequestSender.TIMED_OUT && status !=
RequestSender.GENERATED_REJECTED_OVERLOAD && status !=
RequestSender.INTERNAL_ERROR) {
if(logMINOR) Logger.minor(this, "SSK fetch cost
"+rs.getTotalSentBytes()+ '/' +rs.getTotalReceivedBytes()+" bytes ("+status+
')');
-
node.localSskFetchBytesSentAverage.report(rs.getTotalSentBytes());
-
node.localSskFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
+
nodeStats.localSskFetchBytesSentAverage.report(rs.getTotalSentBytes());
+
nodeStats.localSskFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
}
if((status == RequestSender.TIMED_OUT) ||
@@ -670,8 +687,8 @@
int sent = is.getTotalSentBytes();
int received = is.getTotalReceivedBytes();
if(logMINOR) Logger.minor(this, "Local CHK insert cost "+sent+
'/' +received+" bytes ("+status+ ')');
- node.localChkInsertBytesSentAverage.report(sent);
- node.localChkInsertBytesReceivedAverage.report(received);
+ nodeStats.localChkInsertBytesSentAverage.report(sent);
+ nodeStats.localChkInsertBytesReceivedAverage.report(received);
}
if(status == CHKInsertSender.SUCCESS) {
@@ -777,8 +794,8 @@
int sent = is.getTotalSentBytes();
int received = is.getTotalReceivedBytes();
if(logMINOR) Logger.minor(this, "Local SSK insert cost "+sent+
'/' +received+" bytes ("+status+ ')');
- node.localSskInsertBytesSentAverage.report(sent);
- node.localSskInsertBytesReceivedAverage.report(received);
+ nodeStats.localSskInsertBytesSentAverage.report(sent);
+ nodeStats.localSskInsertBytesReceivedAverage.report(received);
}
if(is.hasCollided()) {
@@ -970,4 +987,8 @@
if(filename == null) return false;
}
}
+
+ public SimpleFieldSet persistThrottlesToFieldSet() {
+ return requestStarters.persistToFieldSet();
+ }
}
Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -38,9 +38,11 @@
private static boolean logMINOR;
final Node node;
+ final NodeStats nodeStats;
NodeDispatcher(Node node) {
this.node = node;
+ this.nodeStats = node.nodeStats;
logMINOR = Logger.shouldLog(Logger.MINOR, this);
}
@@ -140,7 +142,7 @@
}
return true;
}
- String rejectReason = node.shouldRejectRequest(!isSSK, false,
isSSK);
+ String rejectReason = nodeStats.shouldRejectRequest(!isSSK,
false, isSSK);
if(rejectReason != null) {
// can accept 1 CHK request every so often, but not
with SSKs because they aren't throttled so won't sort out bwlimitDelayTime,
which was the whole reason for accepting them when overloaded...
Logger.normal(this, "Rejecting request from
"+m.getSource().getPeer()+" preemptively because "+rejectReason);
@@ -185,7 +187,7 @@
return true;
}
// SSKs don't fix bwlimitDelayTime so shouldn't be accepted
when overloaded.
- String rejectReason = node.shouldRejectRequest(!isSSK, true,
isSSK);
+ String rejectReason = nodeStats.shouldRejectRequest(!isSSK,
true, isSSK);
if(rejectReason != null) {
Logger.normal(this, "Rejecting insert from
"+m.getSource().getPeer()+" preemptively because "+rejectReason);
Message rejected = DMT.createFNPRejectedOverload(id,
true);
Added: trunk/freenet/src/freenet/node/NodeStats.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeStats.java
(rev 0)
+++ trunk/freenet/src/freenet/node/NodeStats.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -0,0 +1,723 @@
+package freenet.node;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import freenet.config.InvalidConfigValueException;
+import freenet.config.SubConfig;
+import freenet.crypt.RandomSource;
+import freenet.io.comm.DMT;
+import freenet.io.comm.IOStatisticCollector;
+import freenet.node.Node.NodeInitException;
+import freenet.support.Logger;
+import freenet.support.OOMHandler;
+import freenet.support.SimpleFieldSet;
+import freenet.support.SizeUtil;
+import freenet.support.TimeUtil;
+import freenet.support.TokenBucket;
+import freenet.support.api.IntCallback;
+import freenet.support.api.StringCallback;
+import freenet.support.math.RunningAverage;
+import freenet.support.math.TimeDecayingRunningAverage;
+
+/** Node (as opposed to NodeClientCore) level statistics. Includes
shouldRejectRequest(), but not limited
+ * to stuff required to implement that. */
+public class NodeStats implements Persistable {
+
+ /** Minimum free heap memory bytes required to accept a request
(perhaps fewer OOMs this way) */
+ public static final long MIN_FREE_HEAP_BYTES_FOR_ROUTING_SUCCESS = 3L *
1024 * 1024; // 3 MiB
+
+ /** Minimum free heap memory percentage required to accept a request
(perhaps fewer OOMs this way) */
+ public static final double MIN_FREE_HEAP_PERCENT_FOR_ROUTING_SUCCESS =
0.01; // 1%
+
+ /** Sub-max ping time. If ping is greater than this, we reject some
requests. */
+ public static final long SUB_MAX_PING_TIME = 700;
+ /** Maximum overall average ping time. If ping is greater than this,
+ * we reject all requests. */
+ public static final long MAX_PING_TIME = 1500;
+ /** Maximum throttled packet delay. If the throttled packet delay is
greater
+ * than this, reject all packets. */
+ public static final long MAX_THROTTLE_DELAY = 3000;
+ /** If the throttled packet delay is less than this, reject no packets;
if it's
+ * between the two, reject some packets. */
+ public static final long SUB_MAX_THROTTLE_DELAY = 2000;
+ /** How high can bwlimitDelayTime be before we alert (in milliseconds)*/
+ public static final long MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD =
MAX_THROTTLE_DELAY*2;
+ /** How high can nodeAveragePingTime be before we alert (in
milliseconds)*/
+ public static final long MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD =
MAX_PING_TIME*2;
+ /** How long we're over the bwlimitDelayTime threshold before we alert
(in milliseconds)*/
+ public static final long MAX_BWLIMIT_DELAY_TIME_ALERT_DELAY =
10*60*1000; // 10 minutes
+ /** How long we're over the nodeAveragePingTime threshold before we
alert (in milliseconds)*/
+ public static final long MAX_NODE_AVERAGE_PING_TIME_ALERT_DELAY =
10*60*1000; // 10 minutes
+ /** Accept one request every 10 seconds regardless, to ensure we update
the
+ * block send time.
+ */
+ public static final int MAX_INTERREQUEST_TIME = 10*1000;
+
+ private final Node node;
+ public final PeerManager peers;
+
+ final RandomSource hardRandom;
+
+ private boolean logMINOR;
+
+ /** Memory Checker thread */
+ private final Thread myMemoryChecker;
+
+ /** first time bwlimitDelay was over PeerManagerUserAlert threshold */
+ private long firstBwlimitDelayTimeThresholdBreak ;
+ /** first time nodeAveragePing was over PeerManagerUserAlert threshold
*/
+ private long firstNodeAveragePingTimeThresholdBreak;
+ /** bwlimitDelay PeerManagerUserAlert should happen if true */
+ public boolean bwlimitDelayAlertRelevant;
+ /** nodeAveragePing PeerManagerUserAlert should happen if true */
+ public boolean nodeAveragePingAlertRelevant;
+ /** Average proportion of requests rejected immediately due to overload
*/
+ public final TimeDecayingRunningAverage pInstantRejectIncoming;
+
+ /** Average delay caused by throttling for sending a packet */
+ final TimeDecayingRunningAverage throttledPacketSendAverage;
+
+ // Stats
+ final TimeDecayingRunningAverage remoteChkFetchBytesSentAverage;
+ final TimeDecayingRunningAverage remoteSskFetchBytesSentAverage;
+ final TimeDecayingRunningAverage remoteChkInsertBytesSentAverage;
+ final TimeDecayingRunningAverage remoteSskInsertBytesSentAverage;
+ final TimeDecayingRunningAverage remoteChkFetchBytesReceivedAverage;
+ final TimeDecayingRunningAverage remoteSskFetchBytesReceivedAverage;
+ final TimeDecayingRunningAverage remoteChkInsertBytesReceivedAverage;
+ final TimeDecayingRunningAverage remoteSskInsertBytesReceivedAverage;
+ final TimeDecayingRunningAverage localChkFetchBytesSentAverage;
+ final TimeDecayingRunningAverage localSskFetchBytesSentAverage;
+ final TimeDecayingRunningAverage localChkInsertBytesSentAverage;
+ final TimeDecayingRunningAverage localSskInsertBytesSentAverage;
+ final TimeDecayingRunningAverage localChkFetchBytesReceivedAverage;
+ final TimeDecayingRunningAverage localSskFetchBytesReceivedAverage;
+ final TimeDecayingRunningAverage localChkInsertBytesReceivedAverage;
+ final TimeDecayingRunningAverage localSskInsertBytesReceivedAverage;
+
+ File persistTarget;
+ File persistTemp;
+ private long previous_input_stat;
+ private long previous_output_stat;
+ private long previous_io_stat_time;
+ private long last_input_stat;
+ private long last_output_stat;
+ private long last_io_stat_time;
+ private final Object ioStatSync = new Object();
+ /** Next time to update the node I/O stats */
+ private long nextNodeIOStatsUpdateTime = -1;
+ /** Node I/O stats update interval (milliseconds) */
+ private static final long nodeIOStatsUpdateInterval = 2000;
+
+ /** Token bucket for output bandwidth used by requests */
+ final TokenBucket requestOutputThrottle;
+ /** Token bucket for input bandwidth used by requests */
+ 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);
+ protected final Persister persister;
+
+ // ThreadCounting stuffs
+ private final ThreadGroup rootThreadGroup;
+ private int threadLimit;
+
+ final NodePinger nodePinger;
+
+ // Peers stats
+ /** Next time to update PeerManagerUserAlert stats */
+ private long nextPeerManagerUserAlertStatsUpdateTime = -1;
+ /** PeerManagerUserAlert stats update interval (milliseconds) */
+ private static final long peerManagerUserAlertStatsUpdateInterval =
1000; // 1 second
+
+ NodeStats(Node node, int sortOrder, SubConfig statsConfig,
SimpleFieldSet oldThrottleFS, int obwLimit, int ibwLimit) throws
NodeInitException {
+ logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ this.node = node;
+ this.peers = node.peers;
+ this.hardRandom = node.random;
+ pInstantRejectIncoming = new TimeDecayingRunningAverage(0,
60000, 0.0, 1.0);
+ 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);
+ //Memory Checking thread
+ // TODO: proper config. callbacks : maybe we shoudln't start
the thread at all if it's not worthy
+ this.myMemoryChecker = new Thread(new MemoryChecker(), "Memory
checker");
+ this.myMemoryChecker.setPriority(Thread.MAX_PRIORITY);
+ this.myMemoryChecker.setDaemon(true);
+
+ nodePinger = new NodePinger(node);
+
+ previous_input_stat = 0;
+ previous_output_stat = 0;
+ previous_io_stat_time = 1;
+ last_input_stat = 0;
+ last_output_stat = 0;
+ last_io_stat_time = 3;
+
+ statsConfig.register("threadLimit", 300, sortOrder++, true,
true, "Thread limit", "The node will try to limit its thread usage to the
specified value, refusing new requests",
+ new IntCallback() {
+ public int get() {
+ return threadLimit;
+ }
+ public void set(int val) throws
InvalidConfigValueException {
+ if(val == get()) return;
+ if(val < 250)
+ throw new
InvalidConfigValueException("This value is to low for that setting, increase
it!");
+ threadLimit = val;
+ }
+ });
+
+
+ threadLimit = statsConfig.getInt("threadLimit");
+
+ persister = new ConfigurablePersister(this, statsConfig,
"throttleFile", "node-throttle.dat", sortOrder++, true, false,
+ "File to store node statistics in", "File to
store node statistics in (not client statistics, and these are used to decide
whether to accept requests so please don't delete)");
+
+ SimpleFieldSet throttleFS = persister.read();
+
+ if(throttleFS == null)
+ throttleFS = oldThrottleFS;
+
+ 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"));
+
+ 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"));
+
+ requestOutputThrottle =
+ new TokenBucket(Math.max(obwLimit*60, 32768*20),
(1000L*1000L*1000L) / obwLimit, 0);
+ requestInputThrottle =
+ new TokenBucket(Math.max(ibwLimit*60, 32768*20),
(1000L*1000L*1000L) / ibwLimit, 0);
+ }
+
+ public void start() throws NodeInitException {
+ nodePinger.start();
+ myMemoryChecker.start();
+ persister.start();
+ }
+
+ private long lastAcceptedRequest = -1;
+
+ private long lastCheckedUncontended = -1;
+
+ static final int ESTIMATED_SIZE_OF_ONE_THROTTLED_PACKET =
+ 1024 + DMT.packetTransmitSize(1024, 32)
+ + FNPPacketMangler.HEADERS_LENGTH_ONE_MESSAGE;
+
+ /* return reject reason as string if should reject, otherwise return
null */
+ public String shouldRejectRequest(boolean canAcceptAnyway, boolean
isInsert, boolean isSSK) {
+ if(logMINOR) dumpByteCostAverages();
+
+ if(threadLimit < getActiveThreadCount())
+ return "Accepting the request would mean going above
the maximum number of allowed threads";
+
+ double bwlimitDelayTime =
throttledPacketSendAverage.currentValue();
+
+ // If no recent reports, no packets have been sent; correct the
average downwards.
+ long now = System.currentTimeMillis();
+ boolean checkUncontended = false;
+ synchronized(this) {
+ if(now - lastCheckedUncontended > 1000) {
+ checkUncontended = true;
+ lastCheckedUncontended = now;
+ }
+ }
+ if(checkUncontended &&
throttledPacketSendAverage.lastReportTime() < now - 5000) { // if last report
more than 5 seconds ago
+ // shouldn't take long
+
node.outputThrottle.blockingGrab(ESTIMATED_SIZE_OF_ONE_THROTTLED_PACKET);
+
node.outputThrottle.recycle(ESTIMATED_SIZE_OF_ONE_THROTTLED_PACKET);
+ long after = System.currentTimeMillis();
+ // Report time it takes to grab the bytes.
+ throttledPacketSendAverage.report(after - now);
+ now = after;
+ // will have changed, use new value
+ synchronized(this) {
+ bwlimitDelayTime =
throttledPacketSendAverage.currentValue();
+ }
+ }
+
+ double pingTime = nodePinger.averagePingTime();
+ synchronized(this) {
+ // Round trip time
+ if(pingTime > MAX_PING_TIME) {
+ if((now - lastAcceptedRequest >
MAX_INTERREQUEST_TIME) && canAcceptAnyway) {
+ if(logMINOR) Logger.minor(this,
"Accepting request anyway (take one every 10 secs to keep bwlimitDelayTime
updated)");
+ } else {
+ pInstantRejectIncoming.report(1.0);
+ return ">MAX_PING_TIME
("+TimeUtil.formatTime((long)pingTime, 2, true)+ ')';
+ }
+ } else if(pingTime > SUB_MAX_PING_TIME) {
+ double x = ((double)(pingTime -
SUB_MAX_PING_TIME)) / (MAX_PING_TIME - SUB_MAX_PING_TIME);
+ if(hardRandom.nextDouble() < x) {
+ pInstantRejectIncoming.report(1.0);
+ return ">SUB_MAX_PING_TIME
("+TimeUtil.formatTime((long)pingTime, 2, true)+ ')';
+ }
+ }
+
+ // Bandwidth limited packets
+ if(bwlimitDelayTime > MAX_THROTTLE_DELAY) {
+ if((now - lastAcceptedRequest >
MAX_INTERREQUEST_TIME) && canAcceptAnyway) {
+ if(logMINOR) Logger.minor(this,
"Accepting request anyway (take one every 10 secs to keep bwlimitDelayTime
updated)");
+ } else {
+ pInstantRejectIncoming.report(1.0);
+ return ">MAX_THROTTLE_DELAY
("+TimeUtil.formatTime((long)bwlimitDelayTime, 2, true)+ ')';
+ }
+ } else if(bwlimitDelayTime > SUB_MAX_THROTTLE_DELAY) {
+ double x = ((double)(bwlimitDelayTime -
SUB_MAX_THROTTLE_DELAY)) / (MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
+ if(hardRandom.nextDouble() < x) {
+ pInstantRejectIncoming.report(1.0);
+ return ">SUB_MAX_THROTTLE_DELAY
("+TimeUtil.formatTime((long)bwlimitDelayTime, 2, true)+ ')';
+ }
+ }
+
+ }
+
+ // Do we have the bandwidth?
+ double expected =
+ (isInsert ? (isSSK ?
this.remoteSskInsertBytesSentAverage : this.remoteChkInsertBytesSentAverage)
+ : (isSSK ?
this.remoteSskFetchBytesSentAverage :
this.remoteChkFetchBytesSentAverage)).currentValue();
+ int expectedSent = (int)Math.max(expected, 0);
+ if(!requestOutputThrottle.instantGrab(expectedSent)) {
+ pInstantRejectIncoming.report(1.0);
+ return "Insufficient output bandwidth";
+ }
+ expected =
+ (isInsert ? (isSSK ?
this.remoteSskInsertBytesReceivedAverage :
this.remoteChkInsertBytesReceivedAverage)
+ : (isSSK ?
this.remoteSskFetchBytesReceivedAverage :
this.remoteChkFetchBytesReceivedAverage)).currentValue();
+ int expectedReceived = (int)Math.max(expected, 0);
+ if(!requestInputThrottle.instantGrab(expectedReceived)) {
+ requestOutputThrottle.recycle(expectedSent);
+ pInstantRejectIncoming.report(1.0);
+ return "Insufficient input bandwidth";
+ }
+
+ Runtime r = Runtime.getRuntime();
+ long maxHeapMemory = r.maxMemory();
+ long freeHeapMemory = r.freeMemory();
+ if(freeHeapMemory < MIN_FREE_HEAP_BYTES_FOR_ROUTING_SUCCESS) {
+ pInstantRejectIncoming.report(1.0);
+ return "<MIN_FREE_HEAP_BYTES_FOR_ROUTING_SUCCESS
("+SizeUtil.formatSize(freeHeapMemory, false)+" of
"+SizeUtil.formatSize(maxHeapMemory, false)+')';
+ }
+ double percentFreeHeapMemoryOfMax = ((double) freeHeapMemory) /
((double) maxHeapMemory);
+ if(percentFreeHeapMemoryOfMax <
MIN_FREE_HEAP_PERCENT_FOR_ROUTING_SUCCESS) {
+ pInstantRejectIncoming.report(1.0);
+ DecimalFormat fix3p1pct = new DecimalFormat("##0.0%");
+ return "<MIN_FREE_HEAP_PERCENT_FOR_ROUTING_SUCCESS
("+SizeUtil.formatSize(freeHeapMemory, false)+" of
"+SizeUtil.formatSize(maxHeapMemory, false)+"
("+fix3p1pct.format(percentFreeHeapMemoryOfMax)+"))";
+ }
+
+ synchronized(this) {
+ if(logMINOR) Logger.minor(this, "Accepting request?");
+ lastAcceptedRequest = now;
+ }
+
+ pInstantRejectIncoming.report(0.0);
+
+ // Accept
+ return null;
+ }
+
+ private void dumpByteCostAverages() {
+ Logger.minor(this, "Byte cost averages: REMOTE:"+
+ " CHK insert
"+remoteChkInsertBytesSentAverage.currentValue()+ '/'
+remoteChkInsertBytesReceivedAverage.currentValue()+
+ " SSK insert
"+remoteSskInsertBytesSentAverage.currentValue()+ '/'
+remoteSskInsertBytesReceivedAverage.currentValue()+
+ " CHK fetch
"+remoteChkFetchBytesSentAverage.currentValue()+ '/'
+remoteChkFetchBytesReceivedAverage.currentValue()+
+ " SSK fetch
"+remoteSskFetchBytesSentAverage.currentValue()+ '/'
+remoteSskFetchBytesReceivedAverage.currentValue());
+ Logger.minor(this, "Byte cost averages: LOCAL"+
+ " CHK insert
"+localChkInsertBytesSentAverage.currentValue()+ '/'
+localChkInsertBytesReceivedAverage.currentValue()+
+ " SSK insert
"+localSskInsertBytesSentAverage.currentValue()+ '/'
+localSskInsertBytesReceivedAverage.currentValue()+
+ " CHK fetch
"+localChkFetchBytesSentAverage.currentValue()+ '/'
+localChkFetchBytesReceivedAverage.currentValue()+
+ " SSK fetch
"+localSskFetchBytesSentAverage.currentValue()+ '/'
+localSskFetchBytesReceivedAverage.currentValue());
+ }
+
+ public double getBwlimitDelayTime() {
+ return throttledPacketSendAverage.currentValue();
+ }
+
+ public double getNodeAveragePingTime() {
+ return nodePinger.averagePingTime();
+ }
+
+ public int getNetworkSizeEstimate(long timestamp) {
+ return node.lm.getNetworkSizeEstimate( timestamp );
+ }
+
+ public Object[] getKnownLocations(long timestamp) {
+ return node.lm.getKnownLocations( timestamp );
+ }
+
+ public double pRejectIncomingInstantly() {
+ return pInstantRejectIncoming.currentValue();
+ }
+
+ /**
+ * Update peerManagerUserAlertStats if the timer has expired
+ */
+ public void maybeUpdatePeerManagerUserAlertStats(long now) {
+ if(now > nextPeerManagerUserAlertStatsUpdateTime) {
+ if(getBwlimitDelayTime() >
MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD) {
+ if(firstBwlimitDelayTimeThresholdBreak == 0) {
+ firstBwlimitDelayTimeThresholdBreak =
now;
+ }
+ } else {
+ firstBwlimitDelayTimeThresholdBreak = 0;
+ }
+ if((firstBwlimitDelayTimeThresholdBreak != 0) && ((now
- firstBwlimitDelayTimeThresholdBreak) >= MAX_BWLIMIT_DELAY_TIME_ALERT_DELAY)) {
+ bwlimitDelayAlertRelevant = true;
+ } else {
+ bwlimitDelayAlertRelevant = false;
+ }
+ if(getNodeAveragePingTime() >
MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD) {
+ if(firstNodeAveragePingTimeThresholdBreak == 0)
{
+ firstNodeAveragePingTimeThresholdBreak
= now;
+ }
+ } else {
+ firstNodeAveragePingTimeThresholdBreak = 0;
+ }
+ if((firstNodeAveragePingTimeThresholdBreak != 0) &&
((now - firstNodeAveragePingTimeThresholdBreak) >=
MAX_NODE_AVERAGE_PING_TIME_ALERT_DELAY)) {
+ nodeAveragePingAlertRelevant = true;
+ } else {
+ nodeAveragePingAlertRelevant = false;
+ }
+ if(logMINOR && Logger.shouldLog(Logger.DEBUG, this))
Logger.debug(this, "mUPMUAS: "+now+": "+getBwlimitDelayTime()+" >?
"+MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD+" since
"+firstBwlimitDelayTimeThresholdBreak+" ("+bwlimitDelayAlertRelevant+")
"+getNodeAveragePingTime()+" >? "+MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD+"
since "+firstNodeAveragePingTimeThresholdBreak+"
("+nodeAveragePingAlertRelevant+ ')');
+ nextPeerManagerUserAlertStatsUpdateTime = now +
peerManagerUserAlertStatsUpdateInterval;
+ }
+ }
+
+ public SimpleFieldSet persistThrottlesToFieldSet() {
+ SimpleFieldSet fs = new SimpleFieldSet(true);
+ fs.put("RemoteChkFetchBytesSentAverage",
remoteChkFetchBytesSentAverage.exportFieldSet(true));
+ fs.put("RemoteSskFetchBytesSentAverage",
remoteSskFetchBytesSentAverage.exportFieldSet(true));
+ fs.put("RemoteChkInsertBytesSentAverage",
remoteChkInsertBytesSentAverage.exportFieldSet(true));
+ fs.put("RemoteSskInsertBytesSentAverage",
remoteSskInsertBytesSentAverage.exportFieldSet(true));
+ fs.put("RemoteChkFetchBytesReceivedAverage",
remoteChkFetchBytesReceivedAverage.exportFieldSet(true));
+ fs.put("RemoteSskFetchBytesReceivedAverage",
remoteSskFetchBytesReceivedAverage.exportFieldSet(true));
+ fs.put("RemoteChkInsertBytesReceivedAverage",
remoteChkInsertBytesReceivedAverage.exportFieldSet(true));
+ fs.put("RemoteSskInsertBytesReceivedAverage",
remoteSskInsertBytesReceivedAverage.exportFieldSet(true));
+ fs.put("LocalChkFetchBytesSentAverage",
localChkFetchBytesSentAverage.exportFieldSet(true));
+ fs.put("LocalSskFetchBytesSentAverage",
localSskFetchBytesSentAverage.exportFieldSet(true));
+ fs.put("LocalChkInsertBytesSentAverage",
localChkInsertBytesSentAverage.exportFieldSet(true));
+ fs.put("LocalSskInsertBytesSentAverage",
localSskInsertBytesSentAverage.exportFieldSet(true));
+ fs.put("LocalChkFetchBytesReceivedAverage",
localChkFetchBytesReceivedAverage.exportFieldSet(true));
+ fs.put("LocalSskFetchBytesReceivedAverage",
localSskFetchBytesReceivedAverage.exportFieldSet(true));
+ fs.put("LocalChkInsertBytesReceivedAverage",
localChkInsertBytesReceivedAverage.exportFieldSet(true));
+ fs.put("LocalSskInsertBytesReceivedAverage",
localSskInsertBytesReceivedAverage.exportFieldSet(true));
+ return fs;
+ }
+
+ /**
+ * Update the node-wide bandwidth I/O stats if the timer has expired
+ */
+ public void maybeUpdateNodeIOStats(long now) {
+ if(now > nextNodeIOStatsUpdateTime) {
+ long[] io_stats = IOStatisticCollector.getTotalIO();
+ long outdiff;
+ long indiff;
+ synchronized(ioStatSync) {
+ previous_output_stat = last_output_stat;
+ previous_input_stat = last_input_stat;
+ previous_io_stat_time = last_io_stat_time;
+ last_output_stat = io_stats[ 0 ];
+ last_input_stat = io_stats[ 1 ];
+ last_io_stat_time = now;
+ outdiff = last_output_stat -
previous_output_stat;
+ indiff = last_input_stat - previous_input_stat;
+ }
+ if(logMINOR)
+ Logger.minor(this, "Last 2 seconds: input:
"+indiff+" output: "+outdiff);
+ nextNodeIOStatsUpdateTime = now +
nodeIOStatsUpdateInterval;
+ }
+ }
+
+ public long[] getNodeIOStats() {
+ long[] result = new long[6];
+ synchronized(ioStatSync) {
+ result[ 0 ] = previous_output_stat;
+ result[ 1 ] = previous_input_stat;
+ result[ 2 ] = previous_io_stat_time;
+ result[ 3 ] = last_output_stat;
+ result[ 4 ] = last_input_stat;
+ result[ 5 ] = last_io_stat_time;
+ }
+ return result;
+ }
+
+ public void waitUntilNotOverloaded(boolean isInsert) {
+ while(threadLimit < getActiveThreadCount()){
+ try{
+ wait(5000);
+ } catch (InterruptedException e) {}
+ }
+ }
+
+
+ public int getActiveThreadCount() {
+ return rootThreadGroup.activeCount();
+ }
+
+ public int getThreadLimit() {
+ return threadLimit;
+ }
+
+ public SimpleFieldSet exportVolatileFieldSet() {
+ SimpleFieldSet fs = new SimpleFieldSet(true);
+ long now = System.currentTimeMillis();
+ fs.put("isUsingWrapper", node.isUsingWrapper());
+ long nodeUptimeSeconds = 0;
+ synchronized(this) {
+ fs.put("startupTime", node.startupTime);
+ nodeUptimeSeconds = (now - node.startupTime) / 1000;
+ fs.put("uptimeSeconds", nodeUptimeSeconds);
+ }
+ fs.put("averagePingTime", getNodeAveragePingTime());
+ fs.put("bwlimitDelayTime", getBwlimitDelayTime());
+ fs.put("networkSizeEstimateSession",
getNetworkSizeEstimate(-1));
+ int networkSizeEstimate24hourRecent =
getNetworkSizeEstimate(now - (24*60*60*1000)); // 24 hours
+ fs.put("networkSizeEstimate24hourRecent",
networkSizeEstimate24hourRecent);
+ int networkSizeEstimate48hourRecent =
getNetworkSizeEstimate(now - (48*60*60*1000)); // 48 hours
+ fs.put("networkSizeEstimate48hourRecent",
networkSizeEstimate48hourRecent);
+ fs.put("routingMissDistance",
routingMissDistance.currentValue());
+ fs.put("backedOffPercent", backedOffPercent.currentValue());
+ fs.put("pInstantReject", pRejectIncomingInstantly());
+ fs.put("unclaimedFIFOSize", node.usm.getUnclaimedFIFOSize());
+
+ /* gather connection statistics */
+ PeerNodeStatus[] peerNodeStatuses = peers.getPeerNodeStatuses();
+ Arrays.sort(peerNodeStatuses, new Comparator() {
+ public int compare(Object first, Object second) {
+ PeerNodeStatus firstNode = (PeerNodeStatus)
first;
+ PeerNodeStatus secondNode = (PeerNodeStatus)
second;
+ int statusDifference =
firstNode.getStatusValue() - secondNode.getStatusValue();
+ if (statusDifference != 0) {
+ return statusDifference;
+ }
+ return
firstNode.getName().compareToIgnoreCase(secondNode.getName());
+ }
+ });
+
+ int numberOfConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_CONNECTED);
+ int numberOfRoutingBackedOff =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
+ int numberOfTooNew =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_TOO_NEW);
+ int numberOfTooOld =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_TOO_OLD);
+ int numberOfDisconnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISCONNECTED);
+ int numberOfNeverConnected =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED);
+ int numberOfDisabled =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_DISABLED);
+ int numberOfBursting =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_BURSTING);
+ int numberOfListening =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_LISTENING);
+ int numberOfListenOnly =
PeerNodeStatus.getPeerStatusCount(peerNodeStatuses,
PeerManager.PEER_NODE_STATUS_LISTEN_ONLY);
+
+ int numberOfSimpleConnected = numberOfConnected +
numberOfRoutingBackedOff;
+ int numberOfNotConnected = numberOfTooNew + numberOfTooOld +
numberOfDisconnected + numberOfNeverConnected + numberOfDisabled +
numberOfBursting + numberOfListening + numberOfListenOnly;
+
+ fs.put("numberOfConnected", numberOfConnected);
+ fs.put("numberOfRoutingBackedOff", numberOfRoutingBackedOff);
+ fs.put("numberOfTooNew", numberOfTooNew);
+ fs.put("numberOfTooOld", numberOfTooOld);
+ fs.put("numberOfDisconnected", numberOfDisconnected);
+ fs.put("numberOfNeverConnected", numberOfNeverConnected);
+ fs.put("numberOfDisabled", numberOfDisabled);
+ fs.put("numberOfBursting", numberOfBursting);
+ fs.put("numberOfListening", numberOfListening);
+ fs.put("numberOfListenOnly", numberOfListenOnly);
+
+ fs.put("numberOfSimpleConnected", numberOfSimpleConnected);
+ fs.put("numberOfNotConnected", numberOfNotConnected);
+
+ fs.put("numberOfInserts", node.getNumInserts());
+ fs.put("numberOfRequests", node.getNumRequests());
+ fs.put("numberOfTransferringRequests",
node.getNumTransferringRequests());
+ fs.put("numberOfARKFetchers", node.getNumARKFetchers());
+
+ long[] total = IOStatisticCollector.getTotalIO();
+ long total_output_rate = (total[0]) / nodeUptimeSeconds;
+ long total_input_rate = (total[1]) / nodeUptimeSeconds;
+ long totalPayloadOutput = node.getTotalPayloadSent();
+ long total_payload_output_rate = totalPayloadOutput /
nodeUptimeSeconds;
+ int total_payload_output_percent = (int) (100 *
totalPayloadOutput / total[0]);
+ fs.put("totalOutputBytes", total[0]);
+ fs.put("totalOutputRate", total_output_rate);
+ fs.put("totalPayloadOutputBytes", totalPayloadOutput);
+ fs.put("totalPayloadOutputRate", total_payload_output_rate);
+ fs.put("totalPayloadOutputPercent",
total_payload_output_percent);
+ fs.put("totalInputBytes", total[1]);
+ fs.put("totalInputRate", total_input_rate);
+ long[] rate = getNodeIOStats();
+ long delta = (rate[5] - rate[2]) / 1000;
+ long recent_output_rate = (rate[3] - rate[0]) / delta;
+ long recent_input_rate = (rate[4] - rate[1]) / delta;
+ fs.put("recentOutputRate", recent_output_rate);
+ fs.put("recentInputRate", recent_input_rate);
+
+ String [] routingBackoffReasons =
peers.getPeerNodeRoutingBackoffReasons();
+ if(routingBackoffReasons.length != 0) {
+ for(int i=0;i<routingBackoffReasons.length;i++) {
+ fs.put("numberWithRoutingBackoffReasons." +
routingBackoffReasons[i],
peers.getPeerNodeRoutingBackoffReasonSize(routingBackoffReasons[i]));
+ }
+ }
+
+ double swaps = (double)node.getSwaps();
+ double noSwaps = (double)node.getNoSwaps();
+ double numberOfRemotePeerLocationsSeenInSwaps =
(double)node.getNumberOfRemotePeerLocationsSeenInSwaps();
+ fs.putSingle("numberOfRemotePeerLocationsSeenInSwaps",
Double.toString(numberOfRemotePeerLocationsSeenInSwaps));
+ double avgConnectedPeersPerNode = 0.0;
+ if ((numberOfRemotePeerLocationsSeenInSwaps > 0.0) && ((swaps >
0.0) || (noSwaps > 0.0))) {
+ avgConnectedPeersPerNode =
numberOfRemotePeerLocationsSeenInSwaps/(swaps+noSwaps);
+ }
+ fs.putSingle("avgConnectedPeersPerNode",
Double.toString(avgConnectedPeersPerNode));
+
+ int startedSwaps = node.getStartedSwaps();
+ int swapsRejectedAlreadyLocked =
node.getSwapsRejectedAlreadyLocked();
+ int swapsRejectedNowhereToGo =
node.getSwapsRejectedNowhereToGo();
+ int swapsRejectedRateLimit = node.getSwapsRejectedRateLimit();
+ int swapsRejectedLoop = node.getSwapsRejectedLoop();
+ int swapsRejectedRecognizedID =
node.getSwapsRejectedRecognizedID();
+ double locationChangePerSession =
node.getLocationChangeSession();
+ double locationChangePerSwap = 0.0;
+ double locationChangePerMinute = 0.0;
+ double swapsPerMinute = 0.0;
+ double noSwapsPerMinute = 0.0;
+ double swapsPerNoSwaps = 0.0;
+ if (swaps > 0) {
+ locationChangePerSwap = locationChangePerSession/swaps;
+ }
+ if ((swaps > 0.0) && (nodeUptimeSeconds >= 60)) {
+ locationChangePerMinute =
locationChangePerSession/(double)(nodeUptimeSeconds/60.0);
+ }
+ if ((swaps > 0.0) && (nodeUptimeSeconds >= 60)) {
+ swapsPerMinute = swaps/(double)(nodeUptimeSeconds/60.0);
+ }
+ if ((noSwaps > 0.0) && (nodeUptimeSeconds >= 60)) {
+ noSwapsPerMinute =
noSwaps/(double)(nodeUptimeSeconds/60.0);
+ }
+ if ((swaps > 0.0) && (noSwaps > 0.0)) {
+ swapsPerNoSwaps = swaps/noSwaps;
+ }
+ fs.put("locationChangePerSession", locationChangePerSession);
+ fs.put("locationChangePerSwap", locationChangePerSwap);
+ fs.put("locationChangePerMinute", locationChangePerMinute);
+ fs.put("swapsPerMinute", swapsPerMinute);
+ fs.put("noSwapsPerMinute", noSwapsPerMinute);
+ fs.put("swapsPerNoSwaps", swapsPerNoSwaps);
+ fs.put("swaps", swaps);
+ fs.put("noSwaps", noSwaps);
+ fs.put("startedSwaps", startedSwaps);
+ fs.put("swapsRejectedAlreadyLocked",
swapsRejectedAlreadyLocked);
+ fs.put("swapsRejectedNowhereToGo", swapsRejectedNowhereToGo);
+ fs.put("swapsRejectedRateLimit", swapsRejectedRateLimit);
+ fs.put("swapsRejectedLoop", swapsRejectedLoop);
+ fs.put("swapsRejectedRecognizedID", swapsRejectedRecognizedID);
+
+ long fix32kb = 32 * 1024;
+ long cachedKeys = node.getChkDatacache().keyCount();
+ long cachedSize = cachedKeys * fix32kb;
+ long storeKeys = node.getChkDatastore().keyCount();
+ long storeSize = storeKeys * fix32kb;
+ long overallKeys = cachedKeys + storeKeys;
+ long overallSize = cachedSize + storeSize;
+
+ long maxOverallKeys = node.getMaxTotalKeys();
+ long maxOverallSize = maxOverallKeys * fix32kb;
+
+ double percentOverallKeysOfMax =
(double)(overallKeys*100)/(double)maxOverallKeys;
+
+ long cachedStoreHits = node.getChkDatacache().hits();
+ long cachedStoreMisses = node.getChkDatacache().misses();
+ long cacheAccesses = cachedStoreHits + cachedStoreMisses;
+ double percentCachedStoreHitsOfAccesses =
(double)(cachedStoreHits*100) / (double)cacheAccesses;
+ long storeHits = node.getChkDatastore().hits();
+ long storeMisses = node.getChkDatastore().misses();
+ long storeAccesses = storeHits + storeMisses;
+ double percentStoreHitsOfAccesses = (double)(storeHits*100) /
(double)storeAccesses;
+ long overallAccesses = storeAccesses + cacheAccesses;
+ double avgStoreAccessRate =
(double)overallAccesses/(double)nodeUptimeSeconds;
+
+ fs.put("cachedKeys", cachedKeys);
+ fs.put("cachedSize", cachedSize);
+ fs.put("storeKeys", storeKeys);
+ fs.put("storeSize", storeSize);
+ fs.put("overallKeys", overallKeys);
+ fs.put("overallSize", overallSize);
+ fs.put("maxOverallKeys", maxOverallKeys);
+ fs.put("maxOverallSize", maxOverallSize);
+ fs.put("percentOverallKeysOfMax", percentOverallKeysOfMax);
+ fs.put("cachedStoreHits", cachedStoreHits);
+ fs.put("cachedStoreMisses", cachedStoreMisses);
+ fs.put("cacheAccesses", cacheAccesses);
+ fs.put("percentCachedStoreHitsOfAccesses",
percentCachedStoreHitsOfAccesses);
+ fs.put("storeHits", storeHits);
+ fs.put("storeMisses", storeMisses);
+ fs.put("storeAccesses", storeAccesses);
+ fs.put("percentStoreHitsOfAccesses",
percentStoreHitsOfAccesses);
+ fs.put("overallAccesses", overallAccesses);
+ fs.put("avgStoreAccessRate", avgStoreAccessRate);
+
+ Runtime rt = Runtime.getRuntime();
+ float freeMemory = (float) rt.freeMemory();
+ float totalMemory = (float) rt.totalMemory();
+ float maxMemory = (float) rt.maxMemory();
+
+ long usedJavaMem = (long)(totalMemory - freeMemory);
+ long allocatedJavaMem = (long)totalMemory;
+ long maxJavaMem = (long)maxMemory;
+ int availableCpus = rt.availableProcessors();
+
+ fs.put("freeJavaMemory", (long)freeMemory);
+ fs.put("usedJavaMemory", usedJavaMem);
+ fs.put("allocatedJavaMemory", allocatedJavaMem);
+ fs.put("maximumJavaMemory", maxJavaMem);
+ fs.put("availableCPUs", availableCpus);
+ fs.put("runningThreadCount", getActiveThreadCount());
+
+ return fs;
+ }
+
+ public void setOutputLimit(int obwLimit) {
+ obwLimit = (obwLimit * 4) / 5; // fudge factor; take into
account non-request activity
+
requestOutputThrottle.changeNanosAndBucketSize((1000L*1000L*1000L) / obwLimit,
Math.max(obwLimit*60, 32768*20));
+ if(node.inputLimitDefault) {
+ int ibwLimit = obwLimit * 4;
+
requestInputThrottle.changeNanosAndBucketSize((1000L*1000L*1000L) / ibwLimit,
Math.max(ibwLimit*60, 32768*20));
+ }
+ }
+
+ public void setInputLimit(int ibwLimit) {
+
requestInputThrottle.changeNanosAndBucketSize((1000L*1000L*1000L) / ibwLimit,
Math.max(ibwLimit*60, 32768*20));
+ }
+
+ public int getInputLimit() {
+ return (((int) ((1000L * 1000L * 1000L) /
requestInputThrottle.getNanosPerTick())) * 5) / 4;
+ }
+
+ public boolean isTestnetEnabled() {
+ return node.isTestnetEnabled();
+ }
+
+
+}
Modified: trunk/freenet/src/freenet/node/PacketSender.java
===================================================================
--- trunk/freenet/src/freenet/node/PacketSender.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/PacketSender.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -35,6 +35,8 @@
private final TreeMap timedJobsByTime;
final Thread myThread;
final Node node;
+ final PeerManager peers;
+ NodeStats stats;
long lastClearedOldSwapChains;
long lastReportedNoPackets;
long lastReceivedPacketFromAnyNode;
@@ -48,6 +50,7 @@
resendPackets = new LinkedList();
timedJobsByTime = new TreeMap();
this.node = node;
+ this.peers = node.peers;
myThread = new Thread(this, "PacketSender thread for
"+node.portNumber);
myThread.setDaemon(true);
myThread.setPriority(Thread.MAX_PRIORITY);
@@ -110,7 +113,8 @@
}
}
- void start() {
+ void start(NodeStats stats) {
+ this.stats = stats;
Logger.normal(this, "Starting PacketSender");
System.out.println("Starting PacketSender");
long now = System.currentTimeMillis();
@@ -163,15 +167,15 @@
PeerNode pn = nodes[i];
// Only routing backed off nodes should need status updating since
everything else
// should get updated immediately when it's changed
- if(pn.getPeerNodeStatus() ==
Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF) {
+ if(pn.getPeerNodeStatus() ==
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF) {
pn.setPeerNodeStatus(now);
}
}
- node.maybeLogPeerNodeStatusSummary(now);
- node.maybeUpdateOldestNeverConnectedPeerAge(now);
- node.maybeUpdatePeerManagerUserAlertStats(now);
- node.maybeUpdateNodeIOStats(now);
- node.maybeUpdatePeerNodeRoutableConnectionStats(now);
+ peers.maybeLogPeerNodeStatusSummary(now);
+ peers.maybeUpdateOldestNeverConnectedPeerAge(now);
+ stats.maybeUpdatePeerManagerUserAlertStats(now);
+ stats.maybeUpdateNodeIOStats(now);
+ peers.maybeUpdatePeerNodeRoutableConnectionStats(now);
long nextActionTime = Long.MAX_VALUE;
long oldTempNow = now;
for(int i=0;i<nodes.length;i++) {
Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/PeerManager.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -15,6 +15,7 @@
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;
import java.util.ArrayList;
@@ -51,8 +52,38 @@
final String filename;
- final PeerManagerUserAlert ua;
+ private PeerManagerUserAlert ua;
+ // Peers stuff
+ /** age of oldest never connected peer (milliseconds) */
+ private long oldestNeverConnectedPeerAge;
+ /** Next time to update oldestNeverConnectedPeerAge */
+ private long nextOldestNeverConnectedPeerAgeUpdateTime = -1;
+ /** oldestNeverConnectedPeerAge update interval (milliseconds) */
+ private static final long oldestNeverConnectedPeerAgeUpdateInterval =
5000;
+ /** Next time to log the PeerNode status summary */
+ private long nextPeerNodeStatusLogTime = -1;
+ /** PeerNode status summary log interval (milliseconds) */
+ private static final long peerNodeStatusLogInterval = 5000;
+ /** PeerNode statuses, by status */
+ private final HashMap peerNodeStatuses;
+ /** PeerNode routing backoff reasons, by reason */
+ private final HashMap peerNodeRoutingBackoffReasons;
+ /** Next time to update routableConnectionStats */
+ private long nextRoutableConnectionStatsUpdateTime = -1;
+ /** routableConnectionStats update interval (milliseconds) */
+ private static final long routableConnectionStatsUpdateInterval = 7 *
1000; // 7 seconds
+ public static final int PEER_NODE_STATUS_CONNECTED = 1;
+ public static final int PEER_NODE_STATUS_ROUTING_BACKED_OFF = 2;
+ public static final int PEER_NODE_STATUS_TOO_NEW = 3;
+ public static final int PEER_NODE_STATUS_TOO_OLD = 4;
+ public static final int PEER_NODE_STATUS_DISCONNECTED = 5;
+ public static final int PEER_NODE_STATUS_NEVER_CONNECTED = 6;
+ public static final int PEER_NODE_STATUS_DISABLED = 7;
+ public static final int PEER_NODE_STATUS_BURSTING = 8;
+ public static final int PEER_NODE_STATUS_LISTENING = 9;
+ public static final int PEER_NODE_STATUS_LISTEN_ONLY = 10;
+
/**
* Create a PeerManager by reading a list of peers from
* a file.
@@ -62,9 +93,10 @@
public PeerManager(Node node, String filename) {
Logger.normal(this, "Creating PeerManager");
logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ peerNodeStatuses = new HashMap();
+ peerNodeRoutingBackoffReasons = new HashMap();
System.out.println("Creating PeerManager");
this.filename = filename;
- ua = new PeerManagerUserAlert(node);
myPeers = new PeerNode[0];
connectedPeers = new PeerNode[0];
this.node = node;
@@ -161,10 +193,10 @@
if(myPeers[i] == pn) isInPeers=true;
}
int peerNodeStatus = pn.getPeerNodeStatus();
- node.removePeerNodeStatus( peerNodeStatus, pn );
+ removePeerNodeStatus( peerNodeStatus, pn );
String peerNodePreviousRoutingBackoffReason =
pn.getPreviousBackoffReason();
if(peerNodePreviousRoutingBackoffReason != null) {
-
node.removePeerNodeRoutingBackoffReason(peerNodePreviousRoutingBackoffReason,
pn);
+
removePeerNodeRoutingBackoffReason(peerNodePreviousRoutingBackoffReason, pn);
}
pn.removeExtraPeerDataDir();
if(!isInPeers) return false;
@@ -472,11 +504,11 @@
if (calculateMisrouting) {
PeerNode nbo = _closerPeer(pn, routedTo, notIgnored, loc,
ignoreSelf, true, minVersion);
if(nbo != null) {
- node.routingMissDistance.report(distance(best,
nbo.getLocation().getValue()));
- int numberOfConnected =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_CONNECTED);
- int numberOfRoutingBackedOff =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF);
+
node.nodeStats.routingMissDistance.report(distance(best,
nbo.getLocation().getValue()));
+ int numberOfConnected =
getPeerNodeStatusSize(PEER_NODE_STATUS_CONNECTED);
+ int numberOfRoutingBackedOff =
getPeerNodeStatusSize(PEER_NODE_STATUS_ROUTING_BACKED_OFF);
if (numberOfRoutingBackedOff + numberOfConnected > 0 ) {
- node.backedOffPercent.report((double)
numberOfRoutingBackedOff / (double) (numberOfRoutingBackedOff +
numberOfConnected));
+ node.nodeStats.backedOffPercent.report((double)
numberOfRoutingBackedOff / (double) (numberOfRoutingBackedOff +
numberOfConnected));
}
}
}
@@ -684,7 +716,7 @@
synchronized(ua) {
ua.conns = conns;
ua.peers = peers;
- ua.neverConn =
node.getPeerNodeStatusSize(Node.PEER_NODE_STATUS_NEVER_CONNECTED);
+ ua.neverConn =
getPeerNodeStatusSize(PEER_NODE_STATUS_NEVER_CONNECTED);
}
if(anyConnectedPeers())
node.onConnectedPeer();
@@ -722,6 +754,7 @@
}
public void start() {
+ ua = new PeerManagerUserAlert(node.nodeStats);
node.clientCore.alerts.register(ua);
}
@@ -741,4 +774,258 @@
if(countNoBackoff == 0) return count;
return countNoBackoff;
}
+
+ // Stats stuff
+
+ /**
+ * Update oldestNeverConnectedPeerAge if the timer has expired
+ */
+ public void maybeUpdateOldestNeverConnectedPeerAge(long now) {
+ if(now > nextOldestNeverConnectedPeerAgeUpdateTime) {
+ oldestNeverConnectedPeerAge = 0;
+ PeerNode[] peerList = myPeers;
+ for(int i=0;i<peerList.length;i++) {
+ PeerNode pn = peerList[i];
+ if(pn.getPeerNodeStatus() ==
PEER_NODE_STATUS_NEVER_CONNECTED) {
+ if((now - pn.getPeerAddedTime()) >
oldestNeverConnectedPeerAge) {
+ oldestNeverConnectedPeerAge = now -
pn.getPeerAddedTime();
+ }
+ }
+ }
+ if(oldestNeverConnectedPeerAge > 0 && logMINOR)
+ Logger.minor(this, "Oldest never connected peer is
"+oldestNeverConnectedPeerAge+"ms old");
+ nextOldestNeverConnectedPeerAgeUpdateTime = now +
oldestNeverConnectedPeerAgeUpdateInterval;
+ }
+ }
+
+ public long getOldestNeverConnectedPeerAge() {
+ return oldestNeverConnectedPeerAge;
+ }
+
+ /**
+ * Log the current PeerNode status summary if the timer has expired
+ */
+ public void maybeLogPeerNodeStatusSummary(long now) {
+ if(now > nextPeerNodeStatusLogTime) {
+ if((now - nextPeerNodeStatusLogTime) > (10*1000) &&
nextPeerNodeStatusLogTime > 0)
+ Logger.error(this,"maybeLogPeerNodeStatusSummary() not called
for more than 10 seconds ("+(now - nextPeerNodeStatusLogTime)+"). PacketSender
getting bogged down or something?");
+
+ int numberOfConnected = 0;
+ int numberOfRoutingBackedOff = 0;
+ int numberOfTooNew = 0;
+ int numberOfTooOld = 0;
+ int numberOfDisconnected = 0;
+ int numberOfNeverConnected = 0;
+ int numberOfDisabled = 0;
+ int numberOfListenOnly = 0;
+ int numberOfListening = 0;
+ int numberOfBursting = 0;
+
+ PeerNodeStatus[] pns = getPeerNodeStatuses();
+
+ for(int i=0; i<pns.length; i++){
+ switch (pns[i].getStatusValue()) {
+ case PEER_NODE_STATUS_CONNECTED:
+ numberOfConnected++;
+ break;
+ case PEER_NODE_STATUS_ROUTING_BACKED_OFF:
+ numberOfRoutingBackedOff++;
+ break;
+ case PEER_NODE_STATUS_TOO_NEW:
+ numberOfTooNew++;
+ break;
+ case PEER_NODE_STATUS_TOO_OLD:
+ numberOfTooOld++;
+ break;
+ case PEER_NODE_STATUS_DISCONNECTED:
+ numberOfDisconnected++;
+ break;
+ case PEER_NODE_STATUS_NEVER_CONNECTED:
+ numberOfNeverConnected++;
+ break;
+ case PEER_NODE_STATUS_DISABLED:
+ numberOfDisabled++;
+ break;
+ case PEER_NODE_STATUS_LISTEN_ONLY:
+ numberOfListenOnly++;
+ break;
+ case PEER_NODE_STATUS_LISTENING:
+ numberOfListening++;
+ break;
+ case PEER_NODE_STATUS_BURSTING:
+ numberOfBursting++;
+ break;
+ default:
+ Logger.error(this, "Unknown peer status value :
"+pns[i].getStatusValue());
+ break;
+ }
+ }
+ Logger.normal(this, "Connected: "+numberOfConnected+" Routing
Backed Off: "+numberOfRoutingBackedOff+" Too New: "+numberOfTooNew+" Too Old:
"+numberOfTooOld+" Disconnected: "+numberOfDisconnected+" Never Connected:
"+numberOfNeverConnected+" Disabled: "+numberOfDisabled+" Bursting:
"+numberOfBursting+" Listening: "+numberOfListening+" Listen Only:
"+numberOfListenOnly);
+ nextPeerNodeStatusLogTime = now + peerNodeStatusLogInterval;
+ }
+ }
+
+ /**
+ * Add a PeerNode status to the map
+ */
+ public void addPeerNodeStatus(int pnStatus, PeerNode peerNode) {
+ Integer peerNodeStatus = new Integer(pnStatus);
+ HashSet statusSet = null;
+ synchronized(peerNodeStatuses) {
+ if(peerNodeStatuses.containsKey(peerNodeStatus)) {
+ statusSet = (HashSet)
peerNodeStatuses.get(peerNodeStatus);
+ if(statusSet.contains(peerNode)) {
+ Logger.error(this,
"addPeerNodeStatus(): identity '"+peerNode.getIdentityString()+"' already in
peerNodeStatuses as "+peerNode+" with status code "+peerNodeStatus);
+ return;
+ }
+ peerNodeStatuses.remove(peerNodeStatus);
+ } else {
+ statusSet = new HashSet();
+ }
+ if(logMINOR) Logger.minor(this, "addPeerNodeStatus():
adding PeerNode for '"+peerNode.getIdentityString()+"' with status code
"+peerNodeStatus);
+ statusSet.add(peerNode);
+ peerNodeStatuses.put(peerNodeStatus, statusSet);
+ }
+ }
+
+ /**
+ * How many PeerNodes have a particular status?
+ */
+ public int getPeerNodeStatusSize(int pnStatus) {
+ Integer peerNodeStatus = new Integer(pnStatus);
+ HashSet statusSet = null;
+ synchronized(peerNodeStatuses) {
+ if(peerNodeStatuses.containsKey(peerNodeStatus)) {
+ statusSet = (HashSet)
peerNodeStatuses.get(peerNodeStatus);
+ } else {
+ statusSet = new HashSet();
+ }
+ return statusSet.size();
+ }
+ }
+
+ /**
+ * Remove a PeerNode status from the map
+ */
+ public void removePeerNodeStatus(int pnStatus, PeerNode peerNode) {
+ Integer peerNodeStatus = new Integer(pnStatus);
+ HashSet statusSet = null;
+ synchronized(peerNodeStatuses) {
+ if(peerNodeStatuses.containsKey(peerNodeStatus)) {
+ statusSet = (HashSet)
peerNodeStatuses.get(peerNodeStatus);
+ if(!statusSet.contains(peerNode)) {
+ Logger.error(this,
"removePeerNodeStatus(): identity '"+peerNode.getIdentityString()+"' not in
peerNodeStatuses with status code "+peerNodeStatus);
+ return;
+ }
+ peerNodeStatuses.remove(peerNodeStatus);
+ } else {
+ statusSet = new HashSet();
+ }
+ if(logMINOR) Logger.minor(this,
"removePeerNodeStatus(): removing PeerNode for
'"+peerNode.getIdentityString()+"' with status code "+peerNodeStatus);
+ if(statusSet.contains(peerNode)) {
+ statusSet.remove(peerNode);
+ }
+ peerNodeStatuses.put(peerNodeStatus, statusSet);
+ }
+ }
+
+ /**
+ * Add a PeerNode routing backoff reason to the map
+ */
+ public void addPeerNodeRoutingBackoffReason(String
peerNodeRoutingBackoffReason, PeerNode peerNode) {
+ synchronized(peerNodeRoutingBackoffReasons) {
+ HashSet reasonSet = null;
+
if(peerNodeRoutingBackoffReasons.containsKey(peerNodeRoutingBackoffReason)) {
+ reasonSet = (HashSet)
peerNodeRoutingBackoffReasons.get(peerNodeRoutingBackoffReason);
+ if(reasonSet.contains(peerNode)) {
+ Logger.error(this,
"addPeerNodeRoutingBackoffReason(): identity '"+peerNode.getIdentityString()+"'
already in peerNodeRoutingBackoffReasons as "+peerNode+" with status code
"+peerNodeRoutingBackoffReason);
+ return;
+ }
+
peerNodeRoutingBackoffReasons.remove(peerNodeRoutingBackoffReason);
+ } else {
+ reasonSet = new HashSet();
+ }
+ if(logMINOR) Logger.minor(this,
"addPeerNodeRoutingBackoffReason(): adding PeerNode for
'"+peerNode.getIdentityString()+"' with status code
"+peerNodeRoutingBackoffReason);
+ reasonSet.add(peerNode);
+
peerNodeRoutingBackoffReasons.put(peerNodeRoutingBackoffReason, reasonSet);
+ }
+ }
+
+ /**
+ * What are the currently tracked PeerNode routing backoff reasons?
+ */
+ public String [] getPeerNodeRoutingBackoffReasons() {
+ String [] reasonStrings;
+ synchronized(peerNodeRoutingBackoffReasons) {
+ reasonStrings = (String [])
peerNodeRoutingBackoffReasons.keySet().toArray(new
String[peerNodeRoutingBackoffReasons.size()]);
+ }
+ Arrays.sort(reasonStrings);
+ return reasonStrings;
+ }
+
+ /**
+ * How many PeerNodes have a particular routing backoff reason?
+ */
+ public int getPeerNodeRoutingBackoffReasonSize(String
peerNodeRoutingBackoffReason) {
+ HashSet reasonSet = null;
+ synchronized(peerNodeRoutingBackoffReasons) {
+
if(peerNodeRoutingBackoffReasons.containsKey(peerNodeRoutingBackoffReason)) {
+ reasonSet = (HashSet)
peerNodeRoutingBackoffReasons.get(peerNodeRoutingBackoffReason);
+ return reasonSet.size();
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ /**
+ * Remove a PeerNode routing backoff reason from the map
+ */
+ public void removePeerNodeRoutingBackoffReason(String
peerNodeRoutingBackoffReason, PeerNode peerNode) {
+ HashSet reasonSet = null;
+ synchronized(peerNodeRoutingBackoffReasons) {
+
if(peerNodeRoutingBackoffReasons.containsKey(peerNodeRoutingBackoffReason)) {
+ reasonSet = (HashSet)
peerNodeRoutingBackoffReasons.get(peerNodeRoutingBackoffReason);
+ if(!reasonSet.contains(peerNode)) {
+ Logger.error(this,
"removePeerNodeRoutingBackoffReason(): identity
'"+peerNode.getIdentityString()+"' not in peerNodeRoutingBackoffReasons with
status code "+peerNodeRoutingBackoffReason);
+ return;
+ }
+
peerNodeRoutingBackoffReasons.remove(peerNodeRoutingBackoffReason);
+ } else {
+ reasonSet = new HashSet();
+ }
+ if(logMINOR) Logger.minor(this,
"removePeerNodeRoutingBackoffReason(): removing PeerNode for
'"+peerNode.getIdentityString()+"' with status code
"+peerNodeRoutingBackoffReason);
+ if(reasonSet.contains(peerNode)) {
+ reasonSet.remove(peerNode);
+ }
+ if(reasonSet.size() > 0) {
+
peerNodeRoutingBackoffReasons.put(peerNodeRoutingBackoffReason, reasonSet);
+ }
+ }
+ }
+
+ public PeerNodeStatus[] getPeerNodeStatuses() {
+ PeerNodeStatus[] peerNodeStatuses = new
PeerNodeStatus[myPeers.length];
+ for (int peerIndex = 0, peerCount = myPeers.length; peerIndex <
peerCount; peerIndex++) {
+ peerNodeStatuses[peerIndex] =
myPeers[peerIndex].getStatus();
+ }
+ return peerNodeStatuses;
+ }
+
+ /**
+ * Update hadRoutableConnectionCount/routableConnectionCheckCount on
peers if the timer has expired
+ */
+ public void maybeUpdatePeerNodeRoutableConnectionStats(long now) {
+ if(now > nextRoutableConnectionStatsUpdateTime) {
+ if(-1 != nextRoutableConnectionStatsUpdateTime) {
+ PeerNode[] peerList = myPeers;
+ for(int i=0;i<peerList.length;i++) {
+ PeerNode pn = peerList[i];
+ pn.checkRoutableConnectionStatus();
+ }
+ }
+ nextRoutableConnectionStatsUpdateTime = now +
routableConnectionStatsUpdateInterval;
+ }
+ }
+
}
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -175,6 +175,9 @@
/** The Node we serve */
final Node node;
+ /** The PeerManager we serve */
+ final PeerManager peers;
+
/** MessageItem's to send ASAP */
private final LinkedList messagesToSendNow;
@@ -248,7 +251,7 @@
private long connectedTime;
/** The status of this peer node in terms of Node.PEER_NODE_STATUS_* */
- public int peerNodeStatus = Node.PEER_NODE_STATUS_DISCONNECTED;
+ public int peerNodeStatus = PeerManager.PEER_NODE_STATUS_DISCONNECTED;
/** Holds a String-Long pair that shows which message types (as name) have
been send to this peer. */
private final Hashtable localNodeSentMessageTypes = new Hashtable();
@@ -335,6 +338,7 @@
public PeerNode(SimpleFieldSet fs, Node node2, boolean fromLocal) throws
FSParseException, PeerParseException, ReferenceSignatureVerificationException {
logMINOR = Logger.shouldLog(Logger.MINOR, this);
this.node = node2;
+ this.peers = node.peers;
String identityString = fs.get("identity");
if(identityString == null)
throw new PeerParseException("No identity!");
@@ -493,7 +497,7 @@
// Not connected yet; need to handshake
isConnected = false;
- node.addPeerNodeStatus(Node.PEER_NODE_STATUS_DISCONNECTED, this);
+ peers.addPeerNodeStatus(PeerManager.PEER_NODE_STATUS_DISCONNECTED,
this);
messagesToSendNow = new LinkedList();
@@ -1838,7 +1842,7 @@
synchronized(this) {
idle = (int) ((now - timeLastReceivedPacket) / 1000);
}
- if((getPeerNodeStatus() == Node.PEER_NODE_STATUS_NEVER_CONNECTED) &&
(getPeerAddedTime() > 1))
+ if((getPeerNodeStatus() ==
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED) && (getPeerAddedTime() > 1))
idle = (int) ((now - getPeerAddedTime()) / 1000);
return getName()+ '\t' +getPeer()+ '\t' +getIdentityString()+ '\t'
+getLocation().getValue()+ '\t' +getPeerNodeStatusString()+ '\t' +idle;
}
@@ -2203,7 +2207,7 @@
}
public void reportThrottledPacketSendTime(long timeDiff) {
- node.throttledPacketSendAverage.report(timeDiff);
+ node.nodeStats.throttledPacketSendAverage.report(timeDiff);
if(logMINOR) Logger.minor(this, "Reporting throttled packet
send time: "+timeDiff+" to "+getPeer());
}
@@ -2316,50 +2320,50 @@
public String getPeerNodeStatusString() {
int status = getPeerNodeStatus();
- if(status == Node.PEER_NODE_STATUS_CONNECTED)
+ if(status == PeerManager.PEER_NODE_STATUS_CONNECTED)
return "CONNECTED";
- if(status == Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF)
+ if(status == PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF)
return "BACKED OFF";
- if(status == Node.PEER_NODE_STATUS_TOO_NEW)
+ if(status == PeerManager.PEER_NODE_STATUS_TOO_NEW)
return "TOO NEW";
- if(status == Node.PEER_NODE_STATUS_TOO_OLD)
+ if(status == PeerManager.PEER_NODE_STATUS_TOO_OLD)
return "TOO OLD";
- if(status == Node.PEER_NODE_STATUS_DISCONNECTED)
+ if(status == PeerManager.PEER_NODE_STATUS_DISCONNECTED)
return "DISCONNECTED";
- if(status == Node.PEER_NODE_STATUS_NEVER_CONNECTED)
+ if(status == PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED)
return "NEVER CONNECTED";
- if(status == Node.PEER_NODE_STATUS_DISABLED)
+ if(status == PeerManager.PEER_NODE_STATUS_DISABLED)
return "DISABLED";
- if(status == Node.PEER_NODE_STATUS_LISTEN_ONLY)
+ if(status == PeerManager.PEER_NODE_STATUS_LISTEN_ONLY)
return "LISTEN ONLY";
- if(status == Node.PEER_NODE_STATUS_LISTENING)
+ if(status == PeerManager.PEER_NODE_STATUS_LISTENING)
return "LISTENING";
- if(status == Node.PEER_NODE_STATUS_BURSTING)
+ if(status == PeerManager.PEER_NODE_STATUS_BURSTING)
return "BURSTING";
return "UNKNOWN STATUS";
}
public String getPeerNodeStatusCSSClassName() {
int status = getPeerNodeStatus();
- if(status == Node.PEER_NODE_STATUS_CONNECTED)
+ if(status == PeerManager.PEER_NODE_STATUS_CONNECTED)
return "peer_connected";
- if(status == Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF)
+ if(status == PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF)
return "peer_backed_off";
- if(status == Node.PEER_NODE_STATUS_TOO_NEW)
+ if(status == PeerManager.PEER_NODE_STATUS_TOO_NEW)
return "peer_too_new";
- if(status == Node.PEER_NODE_STATUS_TOO_OLD)
+ if(status == PeerManager.PEER_NODE_STATUS_TOO_OLD)
return "peer_too_old";
- if(status == Node.PEER_NODE_STATUS_DISCONNECTED)
+ if(status == PeerManager.PEER_NODE_STATUS_DISCONNECTED)
return "peer_disconnected";
- if(status == Node.PEER_NODE_STATUS_NEVER_CONNECTED)
+ if(status == PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED)
return "peer_never_connected";
- if(status == Node.PEER_NODE_STATUS_DISABLED)
+ if(status == PeerManager.PEER_NODE_STATUS_DISABLED)
return "peer_disabled";
- if(status == Node.PEER_NODE_STATUS_BURSTING)
+ if(status == PeerManager.PEER_NODE_STATUS_BURSTING)
return "peer_bursting";
- if(status == Node.PEER_NODE_STATUS_LISTENING)
+ if(status == PeerManager.PEER_NODE_STATUS_LISTENING)
return "peer_listening";
- if(status == Node.PEER_NODE_STATUS_LISTEN_ONLY)
+ if(status == PeerManager.PEER_NODE_STATUS_LISTEN_ONLY)
return "peer_listen_only";
return "peer_unknown_status";
}
@@ -2370,46 +2374,46 @@
checkConnectionsAndTrackers();
int oldPeerNodeStatus = peerNodeStatus;
if(isRoutable()) { // Function use also updates
timeLastConnected and timeLastRoutable
- peerNodeStatus =
Node.PEER_NODE_STATUS_CONNECTED;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_CONNECTED;
if(now < localRoutingBackedOffUntil ) {
- peerNodeStatus =
Node.PEER_NODE_STATUS_ROUTING_BACKED_OFF;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_ROUTING_BACKED_OFF;
if(!lastRoutingBackoffReason.equals(previousRoutingBackoffReason) ||
(previousRoutingBackoffReason == null)) {
if(previousRoutingBackoffReason
!= null) {
-
node.removePeerNodeRoutingBackoffReason(previousRoutingBackoffReason, this);
+
peers.removePeerNodeRoutingBackoffReason(previousRoutingBackoffReason, this);
}
-
node.addPeerNodeRoutingBackoffReason(lastRoutingBackoffReason, this);
+
peers.addPeerNodeRoutingBackoffReason(lastRoutingBackoffReason, this);
previousRoutingBackoffReason =
lastRoutingBackoffReason;
}
} else {
if(previousRoutingBackoffReason !=
null) {
-
node.removePeerNodeRoutingBackoffReason(previousRoutingBackoffReason, this);
+
peers.removePeerNodeRoutingBackoffReason(previousRoutingBackoffReason, this);
previousRoutingBackoffReason =
null;
}
}
} else if(isDisabled) {
- peerNodeStatus = Node.PEER_NODE_STATUS_DISABLED;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_DISABLED;
} else if(isConnected() &&
verifiedIncompatibleNewerVersion) {
- peerNodeStatus = Node.PEER_NODE_STATUS_TOO_NEW;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_TOO_NEW;
} else if(isConnected &&
verifiedIncompatibleOlderVersion) {
- peerNodeStatus = Node.PEER_NODE_STATUS_TOO_OLD;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_TOO_OLD;
} else if(neverConnected) {
- peerNodeStatus =
Node.PEER_NODE_STATUS_NEVER_CONNECTED;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_NEVER_CONNECTED;
} else if(isListenOnly) {
- peerNodeStatus =
Node.PEER_NODE_STATUS_LISTEN_ONLY;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_LISTEN_ONLY;
} else if(isBursting) {
- peerNodeStatus = Node.PEER_NODE_STATUS_BURSTING;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_BURSTING;
} else if(isBurstOnly) {
- peerNodeStatus =
Node.PEER_NODE_STATUS_LISTENING;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_LISTENING;
} else {
- peerNodeStatus =
Node.PEER_NODE_STATUS_DISCONNECTED;
+ peerNodeStatus =
PeerManager.PEER_NODE_STATUS_DISCONNECTED;
}
if(!isConnected && (previousRoutingBackoffReason !=
null)) {
-
node.removePeerNodeRoutingBackoffReason(previousRoutingBackoffReason, this);
+
peers.removePeerNodeRoutingBackoffReason(previousRoutingBackoffReason, this);
previousRoutingBackoffReason = null;
}
if(peerNodeStatus != oldPeerNodeStatus) {
- node.removePeerNodeStatus( oldPeerNodeStatus, this );
- node.addPeerNodeStatus( peerNodeStatus, this );
+ peers.removePeerNodeStatus( oldPeerNodeStatus,
this );
+ peers.addPeerNodeStatus( peerNodeStatus, this );
}
}
}
Added: trunk/freenet/src/freenet/node/Persistable.java
===================================================================
--- trunk/freenet/src/freenet/node/Persistable.java
(rev 0)
+++ trunk/freenet/src/freenet/node/Persistable.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -0,0 +1,15 @@
+/* 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;
+
+import freenet.support.SimpleFieldSet;
+
+/**
+ * Something that can be persisted to disk in the form of a SimpleFieldSet.
+ */
+public interface Persistable {
+
+ SimpleFieldSet persistThrottlesToFieldSet();
+
+}
Added: trunk/freenet/src/freenet/node/Persister.java
===================================================================
--- trunk/freenet/src/freenet/node/Persister.java
(rev 0)
+++ trunk/freenet/src/freenet/node/Persister.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -0,0 +1,133 @@
+package freenet.node;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+
+import freenet.support.Logger;
+import freenet.support.OOMHandler;
+import freenet.support.SimpleFieldSet;
+
+class Persister implements Runnable {
+
+ Persister(Persistable t, File persistTemp, File persistTarget) {
+ this.persistable = t;
+ this.persistTemp = persistTemp;
+ this.persistTarget = persistTarget;
+ }
+
+ // Subclass must set the others later
+ protected Persister(Persistable t) {
+ this.persistable = t;
+ }
+
+ final Persistable persistable;
+ File persistTemp;
+ File persistTarget;
+
+ void interrupt() {
+ synchronized(this) {
+ notifyAll();
+ }
+ }
+
+ public void run() {
+ while(true) {
+ try {
+ persistThrottle();
+ } catch (OutOfMemoryError e) {
+ OOMHandler.handleOOM(e);
+ System.err.println("Will restart
ThrottlePersister...");
+ } catch (Throwable t) {
+ Logger.error(this, "Caught in
ThrottlePersister: "+t, t);
+ System.err.println("Caught in
ThrottlePersister: "+t);
+ t.printStackTrace();
+ System.err.println("Will restart
ThrottlePersister...");
+ }
+ try {
+ synchronized(this) {
+ wait(60*1000);
+ }
+ } catch (InterruptedException e) {
+ // Maybe it's time to wake up?
+ }
+ }
+ }
+
+ public void persistThrottle() {
+ boolean logMINOR = Logger.shouldLog(Logger.MINOR, this);
+ if(logMINOR) Logger.minor(this, "Trying to persist
throttles...");
+ SimpleFieldSet fs = persistable.persistThrottlesToFieldSet();
+ try {
+ FileOutputStream fos = new
FileOutputStream(persistTemp);
+ // FIXME common pattern, reuse it.
+ BufferedOutputStream bos = new
BufferedOutputStream(fos);
+ OutputStreamWriter osw = new OutputStreamWriter(bos,
"UTF-8");
+ BufferedWriter bw = new BufferedWriter(osw);
+ try {
+ fs.writeTo(bw);
+ } catch (IOException e) {
+ try {
+ fos.close();
+ persistTemp.delete();
+ return;
+ } catch (IOException e1) {
+ // Ignore
+ }
+ }
+ try {
+ bw.close();
+ } catch (IOException e) {
+ // Huh?
+ Logger.error(this, "Caught while closing: "+e,
e);
+ return;
+ }
+ // Try an atomic rename
+ if(!persistTemp.renameTo(persistTarget)) {
+ // Not supported on some systems (Windows)
+ if(!persistTarget.delete()) {
+ if(persistTarget.exists()) {
+ Logger.error(this, "Could not
delete "+persistTarget+" - check permissions");
+ }
+ }
+ if(!persistTemp.renameTo(persistTarget)) {
+ Logger.error(this, "Could not rename
"+persistTemp+" to "+persistTarget+" - check permissions");
+ }
+ }
+ } catch (FileNotFoundException e) {
+ Logger.error(this, "Could not store throttle data to
disk: "+e, e);
+ return;
+ } catch (UnsupportedEncodingException e) {
+ Logger.error(this, "Unsupported encoding: UTF-8 !!!!:
"+e, e);
+ }
+
+ }
+
+ public SimpleFieldSet read() {
+ SimpleFieldSet throttleFS = null;
+ try {
+ throttleFS = SimpleFieldSet.readFrom(persistTarget,
false, true);
+ } catch (IOException e) {
+ try {
+ throttleFS =
SimpleFieldSet.readFrom(persistTemp, false, true);
+ } catch (FileNotFoundException e1) {
+ // Ignore
+ } catch (IOException e1) {
+ Logger.error(this, "Could not read
"+persistTarget+" ("+e+") and could not read "+persistTemp+" either ("+e1+ ')');
+ }
+ }
+ return throttleFS;
+ }
+
+ public void start() {
+ Thread t = new Thread(this, "Persister for "+persistable);
+ t.setDaemon(true);
+ t.start();
+ }
+
+}
Modified: trunk/freenet/src/freenet/node/RequestHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestHandler.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/RequestHandler.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -197,12 +197,12 @@
int rcvd = rs.getTotalReceivedBytes() + receivedBytes;
if(key instanceof NodeSSK) {
if(logMINOR) Logger.minor(this, "Remote SSK fetch cost
"+sent+ '/' +rcvd+" bytes ("+status+ ')');
- node.remoteSskFetchBytesSentAverage.report(sent);
- node.remoteSskFetchBytesReceivedAverage.report(rcvd);
+
node.nodeStats.remoteSskFetchBytesSentAverage.report(sent);
+
node.nodeStats.remoteSskFetchBytesReceivedAverage.report(rcvd);
} else {
if(logMINOR) Logger.minor(this, "Remote CHK fetch cost
"+sent+ '/' +rcvd+" bytes ("+status+ ')');
- node.remoteChkFetchBytesSentAverage.report(sent);
- node.remoteChkFetchBytesReceivedAverage.report(rcvd);
+
node.nodeStats.remoteChkFetchBytesSentAverage.report(sent);
+
node.nodeStats.remoteChkFetchBytesReceivedAverage.report(rcvd);
}
}
Modified: trunk/freenet/src/freenet/node/RequestStarter.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestStarter.java 2007-03-22 19:16:22 UTC
(rev 12276)
+++ trunk/freenet/src/freenet/node/RequestStarter.java 2007-03-22 20:37:23 UTC
(rev 12277)
@@ -47,12 +47,14 @@
final RunningAverage averageOutputBytesPerRequest;
RequestScheduler sched;
final NodeClientCore core;
+ final NodeStats stats;
private long sentRequestTime;
private final boolean isInsert;
public RequestStarter(NodeClientCore node, BaseRequestThrottle
throttle, String name, TokenBucket outputBucket, TokenBucket inputBucket,
RunningAverage averageOutputBytesPerRequest,
RunningAverage averageInputBytesPerRequest, boolean isInsert) {
this.core = node;
+ this.stats = core.nodeStats;
this.throttle = throttle;
this.name = name;
this.outputBucket = outputBucket;
@@ -122,7 +124,7 @@
// Ignore
}
} while(now < sleepUntil);
- core.node.waitUntilNotOverloaded(isInsert);
+ stats.waitUntilNotOverloaded(isInsert);
return;
} else {
if(logMINOR) Logger.minor(this, "Waiting...");
Modified: trunk/freenet/src/freenet/node/RequestStarterGroup.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestStarterGroup.java 2007-03-22
19:16:22 UTC (rev 12276)
+++ trunk/freenet/src/freenet/node/RequestStarterGroup.java 2007-03-22
20:37:23 UTC (rev 12277)
@@ -36,6 +36,7 @@
RequestStarterGroup(Node node, NodeClientCore core, int portNumber,
RandomSource random, Config config, SimpleFieldSet fs) {
SubConfig schedulerConfig = new SubConfig("node.scheduler",
config);
+ NodeStats stats = core.nodeStats;
throttleWindow = new ThrottleWindowManager(2.0, fs == null ?
null : fs.subset("ThrottleWindow"), node);
throttleWindowCHK = new ThrottleWindowManager(2.0, fs == null ?
null : fs.subset("ThrottleWindowCHK"), node);
@@ -43,27 +44,27 @@
throttleWindowInsert = new ThrottleWindowManager(2.0, fs ==
null ? null : fs.subset("ThrottleWindowInsert"), node);
throttleWindowRequest = new ThrottleWindowManager(2.0, fs ==
null ? null : fs.subset("ThrottleWindowRequest"), node);
chkRequestThrottle = new MyRequestThrottle(throttleWindow,
5000, "CHK Request", fs == null ? null : fs.subset("CHKRequestThrottle"),
32768);
- chkRequestStarter = new RequestStarter(core,
chkRequestThrottle, "CHK Request starter ("+portNumber+ ')',
node.requestOutputThrottle, node.requestInputThrottle,
node.localChkFetchBytesSentAverage, node.localChkFetchBytesReceivedAverage,
false);
+ chkRequestStarter = new RequestStarter(core,
chkRequestThrottle, "CHK Request starter ("+portNumber+ ')',
stats.requestOutputThrottle, stats.requestInputThrottle,
stats.localChkFetchBytesSentAverage, stats.localChkFetchBytesReceivedAverage,
false);
chkFetchScheduler = new ClientRequestScheduler(false, false,
random, chkRequestStarter, node, schedulerConfig, "CHKrequester");
chkRequestStarter.setScheduler(chkFetchScheduler);
chkRequestStarter.start();
//insertThrottle = new ChainedRequestThrottle(10000, 2.0F,
requestThrottle);
// FIXME reenable the above
chkInsertThrottle = new MyRequestThrottle(throttleWindow,
20000, "CHK Insert", fs == null ? null : fs.subset("CHKInsertThrottle"), 32768);
- chkInsertStarter = new RequestStarter(core, chkInsertThrottle,
"CHK Insert starter ("+portNumber+ ')', node.requestOutputThrottle,
node.requestInputThrottle, node.localChkInsertBytesSentAverage,
node.localChkInsertBytesReceivedAverage, true);
+ chkInsertStarter = new RequestStarter(core, chkInsertThrottle,
"CHK Insert starter ("+portNumber+ ')', stats.requestOutputThrottle,
stats.requestInputThrottle, stats.localChkInsertBytesSentAverage,
stats.localChkInsertBytesReceivedAverage, true);
chkPutScheduler = new ClientRequestScheduler(true, false,
random, chkInsertStarter, node, schedulerConfig, "CHKinserter");
chkInsertStarter.setScheduler(chkPutScheduler);
chkInsertStarter.start();
sskRequestThrottle = new MyRequestThrottle(throttleWindow,
5000, "SSK Request", fs == null ? null : fs.subset("SSKRequestThrottle"), 1024);
- sskRequestStarter = new RequestStarter(core,
sskRequestThrottle, "SSK Request starter ("+portNumber+ ')',
node.requestOutputThrottle, node.requestInputThrottle,
node.localSskFetchBytesSentAverage, node.localSskFetchBytesReceivedAverage,
false);
+ sskRequestStarter = new RequestStarter(core,
sskRequestThrottle, "SSK Request starter ("+portNumber+ ')',
stats.requestOutputThrottle, stats.requestInputThrottle,
stats.localSskFetchBytesSentAverage, stats.localSskFetchBytesReceivedAverage,
false);
sskFetchScheduler = new ClientRequestScheduler(false, true,
random, sskRequestStarter, node, schedulerConfig, "SSKrequester");
sskRequestStarter.setScheduler(sskFetchScheduler);
sskRequestStarter.start();
//insertThrottle = new ChainedRequestThrottle(10000, 2.0F,
requestThrottle);
// FIXME reenable the above
sskInsertThrottle = new MyRequestThrottle(throttleWindow,
20000, "SSK Insert", fs == null ? null : fs.subset("SSKInsertThrottle"), 1024);
- sskInsertStarter = new RequestStarter(core, sskInsertThrottle,
"SSK Insert starter ("+portNumber+ ')', node.requestOutputThrottle,
node.requestInputThrottle, node.localSskInsertBytesSentAverage,
node.localSskFetchBytesReceivedAverage, true);
+ sskInsertStarter = new RequestStarter(core, sskInsertThrottle,
"SSK Insert starter ("+portNumber+ ')', stats.requestOutputThrottle,
stats.requestInputThrottle, stats.localSskInsertBytesSentAverage,
stats.localSskFetchBytesReceivedAverage, true);
sskPutScheduler = new ClientRequestScheduler(true, true,
random, sskInsertStarter, node, schedulerConfig, "SSKinserter");
sskInsertStarter.setScheduler(sskPutScheduler);
sskInsertStarter.start();
Modified: trunk/freenet/src/freenet/node/SSKInsertHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertHandler.java 2007-03-22
19:16:22 UTC (rev 12276)
+++ trunk/freenet/src/freenet/node/SSKInsertHandler.java 2007-03-22
20:37:23 UTC (rev 12277)
@@ -312,8 +312,8 @@
totalReceived += sender.getTotalReceivedBytes();
}
if(logMINOR) Logger.minor(this, "Remote SSK insert cost
"+totalSent+ '/' +totalReceived+" bytes ("+code+ ')');
- node.remoteSskInsertBytesSentAverage.report(totalSent);
- node.remoteSskInsertBytesReceivedAverage.report(totalReceived);
+
node.nodeStats.remoteSskInsertBytesSentAverage.report(totalSent);
+
node.nodeStats.remoteSskInsertBytesReceivedAverage.report(totalReceived);
}
}
Modified: trunk/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java
===================================================================
--- trunk/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java
2007-03-22 19:16:22 UTC (rev 12276)
+++ trunk/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java
2007-03-22 20:37:23 UTC (rev 12277)
@@ -3,12 +3,12 @@
* http://www.gnu.org/ for further details of the GPL. */
package freenet.node.useralerts;
-import freenet.node.Node;
+import freenet.node.NodeStats;
import freenet.support.HTMLNode;
public class PeerManagerUserAlert implements UserAlert {
- final Node n;
+ final NodeStats n;
public int conns = 0;
public int peers = 0;
public int neverConn = 0;
@@ -35,7 +35,7 @@
/** How high can oldestNeverConnectedPeerAge be before we alert (in
milliseconds)*/
static final long MAX_OLDEST_NEVER_CONNECTED_PEER_AGE_ALERT_THRESHOLD =
((long) 2)*7*24*60*60*1000; // 2 weeks
- public PeerManagerUserAlert(Node n) {
+ public PeerManagerUserAlert(NodeStats n) {
this.n = n;
}
@@ -61,9 +61,9 @@
return "Too many open connections";
if(peers > MAX_PEER_ALERT_THRESHOLD)
return "Too many peers";
- if(n.bwlimitDelayAlertRelevant && (bwlimitDelayTime >
Node.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD))
+ if(n.bwlimitDelayAlertRelevant && (bwlimitDelayTime >
NodeStats.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD))
return "bwlimitDelayTime too high";
- if(n.nodeAveragePingAlertRelevant && (nodeAveragePingTime >
Node.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD))
+ if(n.nodeAveragePingAlertRelevant && (nodeAveragePingTime >
NodeStats.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD))
return "nodeAveragePingTime too high";
if(oldestNeverConnectedPeerAge >
MAX_OLDEST_NEVER_CONNECTED_PEER_AGE_ALERT_THRESHOLD)
return "Never connected peer(s) too old";
@@ -126,11 +126,11 @@
"This will also marginally impact your performance as all peers
(connected or not) consume a small amount of bandwidth and CPU. Consider
\"cleaning up\" your peer list.";
static final String TOO_HIGH_BWLIMITDELAYTIME =
- "This node has to wait too long for available bandwidth
({BWLIMIT_DELAY_TIME} > "+Node.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD+").
Increase your output bandwidth limit and/or remove some peers to improve the
situation.";
+ "This node has to wait too long for available bandwidth
({BWLIMIT_DELAY_TIME} > "+NodeStats.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD+").
Increase your output bandwidth limit and/or remove some peers to improve the
situation.";
static final String TOO_HIGH_PING =
"This node is having trouble talking with its peers quickly
enough ({PING_TIME} > "+
- Node.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD+"). Increase
your output bandwidth limit and/or remove some peers to improve the situation.";
+ NodeStats.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD+").
Increase your output bandwidth limit and/or remove some peers to improve the
situation.";
static final String NEVER_CONNECTED_TWO_WEEKS =
"One or more of your node's peers have never connected in the
two weeks since they were added. Consider removing them since they are
marginally affecting performance.";
@@ -157,11 +157,11 @@
s = replace(TOO_MANY_CONNECTIONS, "\\{CONNS\\}",
Integer.toString(conns));
} else if(peers > MAX_PEER_ALERT_THRESHOLD) {
s = replace(TOO_MANY_PEERS, "\\{PEERS\\}",
Integer.toString(peers));
- } else if(n.bwlimitDelayAlertRelevant && (bwlimitDelayTime >
Node.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) {
+ } else if(n.bwlimitDelayAlertRelevant && (bwlimitDelayTime >
NodeStats.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) {
s = replace(TOO_HIGH_BWLIMITDELAYTIME,
"\\{BWLIMIT_DELAY_TIME\\}", Integer.toString(bwlimitDelayTime));
// FIXME I'm not convinced about the next one!
- } else if(n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > Node.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)) {
+ } else if(n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > NodeStats.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)) {
s = replace(TOO_HIGH_PING, "\\{PING_TIME\\}",
Integer.toString(nodeAveragePingTime));
} else if(oldestNeverConnectedPeerAge >
MAX_OLDEST_NEVER_CONNECTED_PEER_AGE_ALERT_THRESHOLD) {
s = NEVER_CONNECTED_TWO_WEEKS;
@@ -217,9 +217,9 @@
alertNode.addChild("#", replace(TOO_MANY_CONNECTIONS,
"\\{CONNS\\}", Integer.toString(conns)));
} else if (peers > MAX_PEER_ALERT_THRESHOLD) {
alertNode.addChild("#", replace(TOO_MANY_PEERS,
"\\{PEERS\\}", Integer.toString(peers)));
- } else if (n.bwlimitDelayAlertRelevant && (bwlimitDelayTime >
Node.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) {
+ } else if (n.bwlimitDelayAlertRelevant && (bwlimitDelayTime >
NodeStats.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) {
alertNode.addChild("#",
replace(TOO_HIGH_BWLIMITDELAYTIME, "\\{BWLIMIT_DELAY_TIME\\}",
Integer.toString(bwlimitDelayTime)));
- } else if (n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > Node.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)) {
+ } else if (n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > NodeStats.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)) {
alertNode.addChild("#", replace(TOO_HIGH_PING,
"\\{PING_TIME\\}", Integer.toString(nodeAveragePingTime)));
} else if (oldestNeverConnectedPeerAge >
MAX_OLDEST_NEVER_CONNECTED_PEER_AGE_ALERT_THRESHOLD) {
alertNode.addChild("#", NEVER_CONNECTED_TWO_WEEKS);
@@ -235,8 +235,8 @@
((peers - conns) >
MAX_DISCONN_PEER_ALERT_THRESHOLD) ||
(conns > MAX_CONN_ALERT_THRESHOLD) ||
(peers > MAX_PEER_ALERT_THRESHOLD) ||
- (n.bwlimitDelayAlertRelevant &&
(bwlimitDelayTime > Node.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) ||
- (n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > Node.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)))
+ (n.bwlimitDelayAlertRelevant &&
(bwlimitDelayTime > NodeStats.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) ||
+ (n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > NodeStats.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)))
return UserAlert.CRITICAL_ERROR;
return UserAlert.ERROR;
}
@@ -245,15 +245,15 @@
// only update here so we don't get odd behavior with it
fluctuating
bwlimitDelayTime = (int) n.getBwlimitDelayTime();
nodeAveragePingTime = (int) n.getNodeAveragePingTime();
- oldestNeverConnectedPeerAge = (int)
n.getOldestNeverConnectedPeerAge();
+ oldestNeverConnectedPeerAge = (int)
n.peers.getOldestNeverConnectedPeerAge();
return ((peers == 0) ||
(conns < 3) ||
(neverConn >
MAX_NEVER_CONNECTED_PEER_ALERT_THRESHOLD) ||
((peers - conns) >
MAX_DISCONN_PEER_ALERT_THRESHOLD) ||
(conns > MAX_CONN_ALERT_THRESHOLD) ||
(peers > MAX_PEER_ALERT_THRESHOLD) ||
- (n.bwlimitDelayAlertRelevant &&
(bwlimitDelayTime > Node.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) ||
- (n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > Node.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)) ||
+ (n.bwlimitDelayAlertRelevant &&
(bwlimitDelayTime > NodeStats.MAX_BWLIMIT_DELAY_TIME_ALERT_THRESHOLD)) ||
+ (n.nodeAveragePingAlertRelevant &&
(nodeAveragePingTime > NodeStats.MAX_NODE_AVERAGE_PING_TIME_ALERT_THRESHOLD)) ||
(oldestNeverConnectedPeerAge >
MAX_OLDEST_NEVER_CONNECTED_PEER_AGE_ALERT_THRESHOLD)) &&
isValid;
}