Author: toad
Date: 2007-11-29 00:17:12 +0000 (Thu, 29 Nov 2007)
New Revision: 16051
Modified:
trunk/freenet/src/freenet/node/NodeStats.java
trunk/freenet/src/freenet/node/RequestStarter.java
trunk/freenet/src/freenet/node/RequestStarterGroup.java
Log:
Make local requests compete fairly by going through exactly the same
shouldRejectRequest() logic as remote ones.
Good for security.
Probably good for bandwidth/resource limiting.
Maybe not so good for end user performance, but if it improves load management
it'll work out good for them too.
Modified: trunk/freenet/src/freenet/node/NodeStats.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeStats.java 2007-11-29 00:09:21 UTC
(rev 16050)
+++ trunk/freenet/src/freenet/node/NodeStats.java 2007-11-29 00:17:12 UTC
(rev 16051)
@@ -656,7 +656,6 @@
}
}
-
public int getActiveThreadCount() {
return rootThreadGroup.activeCount() -
node.executor.waitingThreads();
}
Modified: trunk/freenet/src/freenet/node/RequestStarter.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestStarter.java 2007-11-29 00:09:21 UTC
(rev 16050)
+++ trunk/freenet/src/freenet/node/RequestStarter.java 2007-11-29 00:17:12 UTC
(rev 16051)
@@ -36,6 +36,10 @@
public static final short NUMBER_OF_PRIORITY_CLASSES =
MINIMUM_PRIORITY_CLASS - MAXIMUM_PRIORITY_CLASS + 1; // include 0 and max !!
+ /** If true, local requests are subject to shouldRejectRequest(). If
false, they are only subject to the token
+ * buckets and the thread limit. FIXME make configurable. */
+ private final boolean LOCAL_REQUESTS_COMPETE_FAIRLY = true;
+
public static boolean isValidPriorityClass(int prio) {
return !((prio < MAXIMUM_PRIORITY_CLASS) || (prio >
MINIMUM_PRIORITY_CLASS));
}
@@ -50,9 +54,10 @@
final NodeStats stats;
private long sentRequestTime;
private final boolean isInsert;
+ private final boolean isSSK;
public RequestStarter(NodeClientCore node, BaseRequestThrottle
throttle, String name, TokenBucket outputBucket, TokenBucket inputBucket,
- RunningAverage averageOutputBytesPerRequest,
RunningAverage averageInputBytesPerRequest, boolean isInsert) {
+ RunningAverage averageOutputBytesPerRequest,
RunningAverage averageInputBytesPerRequest, boolean isInsert, boolean isSSK) {
this.core = node;
this.stats = core.nodeStats;
this.throttle = throttle;
@@ -62,6 +67,7 @@
this.averageOutputBytesPerRequest =
averageOutputBytesPerRequest;
this.averageInputBytesPerRequest = averageInputBytesPerRequest;
this.isInsert = isInsert;
+ this.isSSK = isSSK;
}
void setScheduler(RequestScheduler sched) {
@@ -92,8 +98,10 @@
long delay = throttle.getDelay();
if(logMINOR) Logger.minor(this,
"Delay="+delay+" from "+throttle);
long sleepUntil = sentRequestTime + delay;
- inputBucket.blockingGrab((int)(Math.max(0,
averageInputBytesPerRequest.currentValue())));
- outputBucket.blockingGrab((int)(Math.max(0,
averageOutputBytesPerRequest.currentValue())));
+ if(!LOCAL_REQUESTS_COMPETE_FAIRLY) {
+
inputBucket.blockingGrab((int)(Math.max(0,
averageInputBytesPerRequest.currentValue())));
+
outputBucket.blockingGrab((int)(Math.max(0,
averageOutputBytesPerRequest.currentValue())));
+ }
long now;
do {
now = System.currentTimeMillis();
@@ -105,7 +113,16 @@
// Ignore
}
} while(now < sleepUntil);
- stats.waitUntilNotOverloaded(isInsert);
+ String reason;
+ if(LOCAL_REQUESTS_COMPETE_FAIRLY) {
+ if((reason =
stats.shouldRejectRequest(true, isInsert, isSSK)) != null) {
+ if(logMINOR)
+ Logger.minor(this, "Not
sending local request: "+reason);
+ continue; // Let local requests
compete with all the others
+ }
+ } else {
+ 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-11-29
00:09:21 UTC (rev 16050)
+++ trunk/freenet/src/freenet/node/RequestStarterGroup.java 2007-11-29
00:17:12 UTC (rev 16051)
@@ -44,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+ ')',
stats.requestOutputThrottle, stats.requestInputThrottle,
stats.localChkFetchBytesSentAverage, stats.localChkFetchBytesReceivedAverage,
false);
+ chkRequestStarter = new RequestStarter(core,
chkRequestThrottle, "CHK Request starter ("+portNumber+ ')',
stats.requestOutputThrottle, stats.requestInputThrottle,
stats.localChkFetchBytesSentAverage, stats.localChkFetchBytesReceivedAverage,
false, 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+ ')', stats.requestOutputThrottle,
stats.requestInputThrottle, stats.localChkInsertBytesSentAverage,
stats.localChkInsertBytesReceivedAverage, true);
+ chkInsertStarter = new RequestStarter(core, chkInsertThrottle,
"CHK Insert starter ("+portNumber+ ')', stats.requestOutputThrottle,
stats.requestInputThrottle, stats.localChkInsertBytesSentAverage,
stats.localChkInsertBytesReceivedAverage, true, false);
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+ ')',
stats.requestOutputThrottle, stats.requestInputThrottle,
stats.localSskFetchBytesSentAverage, stats.localSskFetchBytesReceivedAverage,
false);
+ sskRequestStarter = new RequestStarter(core,
sskRequestThrottle, "SSK Request starter ("+portNumber+ ')',
stats.requestOutputThrottle, stats.requestInputThrottle,
stats.localSskFetchBytesSentAverage, stats.localSskFetchBytesReceivedAverage,
false, true);
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+ ')', stats.requestOutputThrottle,
stats.requestInputThrottle, stats.localSskInsertBytesSentAverage,
stats.localSskFetchBytesReceivedAverage, true);
+ sskInsertStarter = new RequestStarter(core, sskInsertThrottle,
"SSK Insert starter ("+portNumber+ ')', stats.requestOutputThrottle,
stats.requestInputThrottle, stats.localSskInsertBytesSentAverage,
stats.localSskFetchBytesReceivedAverage, true, true);
sskPutScheduler = new ClientRequestScheduler(true, true,
random, sskInsertStarter, node, schedulerConfig, "SSKinserter");
sskInsertStarter.setScheduler(sskPutScheduler);
sskInsertStarter.start();