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();


Reply via email to