Author: toad
Date: 2006-08-12 21:21:43 +0000 (Sat, 12 Aug 2006)
New Revision: 10051
Modified:
trunk/freenet/src/freenet/node/RequestStarterGroup.java
trunk/freenet/src/freenet/node/ThrottleWindowManager.java
trunk/freenet/src/freenet/support/SimpleFieldSet.java
trunk/freenet/src/freenet/support/math/BootstrappingDecayingRunningAverage.java
Log:
Restore load limiting throttles from saved data.
Modified: trunk/freenet/src/freenet/node/RequestStarterGroup.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestStarterGroup.java 2006-08-12
20:55:25 UTC (rev 10050)
+++ trunk/freenet/src/freenet/node/RequestStarterGroup.java 2006-08-12
21:21:43 UTC (rev 10051)
@@ -28,6 +28,8 @@
final MyRequestThrottle sskInsertThrottle;
final RequestStarter sskInsertStarter;
final File nodeDir;
+ final File persistTarget;
+ final File persistTemp;
public final ClientRequestScheduler chkFetchScheduler;
public final ClientRequestScheduler chkPutScheduler;
@@ -38,29 +40,44 @@
SubConfig schedulerConfig = new SubConfig("node.scheduler",
config);
this.nodeDir = node.nodeDir;
+ persistTarget = new File(nodeDir, "throttle.dat");
+ persistTemp = new File(nodeDir, "throttle.dat.tmp");
- throttleWindow = new ThrottleWindowManager(2.0);
- chkRequestThrottle = new MyRequestThrottle(throttleWindow,
5000, "CHK Request");
+ SimpleFieldSet fs = null;
+ try {
+ fs = SimpleFieldSet.readFrom(persistTarget);
+ } catch (IOException e) {
+ try {
+ fs = SimpleFieldSet.readFrom(persistTemp);
+ } catch (FileNotFoundException e1) {
+ // Ignore
+ } catch (IOException e1) {
+ Logger.error(this, "Could not read
"+persistTarget+" ("+e+") and could not read "+persistTemp+" either ("+e1+")");
+ }
+ }
+
+ throttleWindow = new ThrottleWindowManager(2.0, fs == null ?
null : fs.subset("ThrottleWindow"));
+ chkRequestThrottle = new MyRequestThrottle(throttleWindow,
5000, "CHK Request", fs == null ? null : fs.subset("CHKRequestThrottle"));
chkRequestStarter = new RequestStarter(core,
chkRequestThrottle, "CHK Request starter ("+portNumber+")",
node.requestOutputThrottle, node.requestInputThrottle,
node.localChkFetchBytesSentAverage, node.localChkFetchBytesReceivedAverage);
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");
+ chkInsertThrottle = new MyRequestThrottle(throttleWindow,
20000, "CHK Insert", fs == null ? null : fs.subset("CHKInsertThrottle"));
chkInsertStarter = new RequestStarter(core, chkInsertThrottle,
"CHK Insert starter ("+portNumber+")", node.requestOutputThrottle,
node.requestInputThrottle, node.localChkInsertBytesSentAverage,
node.localChkInsertBytesReceivedAverage);
chkPutScheduler = new ClientRequestScheduler(true, false,
random, chkInsertStarter, node, schedulerConfig, "CHKinserter");
chkInsertStarter.setScheduler(chkPutScheduler);
chkInsertStarter.start();
- sskRequestThrottle = new MyRequestThrottle(throttleWindow,
5000, "SSK Request");
+ sskRequestThrottle = new MyRequestThrottle(throttleWindow,
5000, "SSK Request", fs == null ? null : fs.subset("SSKRequestThrottle"));
sskRequestStarter = new RequestStarter(core,
sskRequestThrottle, "SSK Request starter ("+portNumber+")",
node.requestOutputThrottle, node.requestInputThrottle,
node.localSskFetchBytesSentAverage, node.localSskFetchBytesReceivedAverage);
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");
+ sskInsertThrottle = new MyRequestThrottle(throttleWindow,
20000, "SSK Insert", fs == null ? null : fs.subset("SSKInsertThrottle"));
sskInsertStarter = new RequestStarter(core, sskInsertThrottle,
"SSK Insert starter ("+portNumber+")", node.requestOutputThrottle,
node.requestInputThrottle, node.localSskInsertBytesSentAverage,
node.localSskFetchBytesReceivedAverage);
sskPutScheduler = new ClientRequestScheduler(true, true,
random, sskInsertStarter, node, schedulerConfig, "SSKinserter");
sskInsertStarter.setScheduler(sskPutScheduler);
@@ -80,9 +97,9 @@
public class MyRequestThrottle implements BaseRequestThrottle {
private final BootstrappingDecayingRunningAverage
roundTripTime;
-
- public MyRequestThrottle(ThrottleWindowManager throttleWindow,
int rtt, String string) {
- roundTripTime = new
BootstrappingDecayingRunningAverage(rtt, 10, 5*60*1000, 10);
+
+ public MyRequestThrottle(ThrottleWindowManager throttleWindow,
int rtt, String string, SimpleFieldSet fs) {
+ roundTripTime = new
BootstrappingDecayingRunningAverage(rtt, 10, 5*60*1000, 10, fs == null ? null :
fs.subset("RoundTripTime"));
}
public synchronized long getDelay() {
@@ -155,10 +172,8 @@
public void persistThrottle() {
SimpleFieldSet fs = persistToFieldSet();
- File target = new File(nodeDir, "throttle.dat");
- File tmp = new File(nodeDir, "throttle.dat.tmp");
try {
- FileOutputStream fos = new FileOutputStream(tmp);
+ FileOutputStream fos = new
FileOutputStream(persistTemp);
// FIXME common pattern, reuse it.
BufferedOutputStream bos = new
BufferedOutputStream(fos);
OutputStreamWriter osw = new OutputStreamWriter(bos,
"UTF-8");
@@ -167,7 +182,7 @@
} catch (IOException e) {
try {
fos.close();
- tmp.delete();
+ persistTemp.delete();
return;
} catch (IOException e1) {
// Ignore
@@ -181,15 +196,15 @@
return;
}
// Try an atomic rename
- if(!tmp.renameTo(target)) {
+ if(!persistTemp.renameTo(persistTarget)) {
// Not supported on some systems (Windows)
- if(!target.delete()) {
- if(target.exists()) {
- Logger.error(this, "Could not
delete "+target+" - check permissions");
+ if(!persistTarget.delete()) {
+ if(persistTarget.exists()) {
+ Logger.error(this, "Could not
delete "+persistTarget+" - check permissions");
}
}
- if(!tmp.renameTo(target)) {
- Logger.error(this, "Could not rename
"+tmp+" to "+target+" - check permissions");
+ if(!persistTemp.renameTo(persistTarget)) {
+ Logger.error(this, "Could not rename
"+persistTemp+" to "+persistTarget+" - check permissions");
}
}
} catch (FileNotFoundException e) {
Modified: trunk/freenet/src/freenet/node/ThrottleWindowManager.java
===================================================================
--- trunk/freenet/src/freenet/node/ThrottleWindowManager.java 2006-08-12
20:55:25 UTC (rev 10050)
+++ trunk/freenet/src/freenet/node/ThrottleWindowManager.java 2006-08-12
21:21:43 UTC (rev 10051)
@@ -11,8 +11,14 @@
private long _totalPackets = 0, _droppedPackets = 0;
private double _simulatedWindowSize = 2;
- public ThrottleWindowManager(double d) {
- _simulatedWindowSize = d;
+ public ThrottleWindowManager(double def, SimpleFieldSet fs) {
+ if(fs != null) {
+ _totalPackets = fs.getInt("TotalPackets", 0);
+ _droppedPackets = fs.getInt("DroppedPackets", 0);
+ _simulatedWindowSize =
fs.getDouble("SimulatedWindowSize", def);
+ } else {
+ _simulatedWindowSize = def;
+ }
}
public synchronized double currentValue() {
Modified: trunk/freenet/src/freenet/support/SimpleFieldSet.java
===================================================================
--- trunk/freenet/src/freenet/support/SimpleFieldSet.java 2006-08-12
20:55:25 UTC (rev 10050)
+++ trunk/freenet/src/freenet/support/SimpleFieldSet.java 2006-08-12
21:21:43 UTC (rev 10051)
@@ -1,10 +1,16 @@
package freenet.support;
+import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
@@ -412,4 +418,61 @@
return (String[]) subsets.keySet().toArray(new
String[subsets.size()]);
}
+ public static SimpleFieldSet readFrom(File f) throws IOException {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(f);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ InputStreamReader isr;
+ try {
+ isr = new InputStreamReader(bis, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ Logger.error(SimpleFieldSet.class, "Impossible:
"+e, e);
+ fis.close();
+ return null;
+ }
+ BufferedReader br = new BufferedReader(isr);
+ SimpleFieldSet fs = new SimpleFieldSet(br);
+ br.close();
+ fis = null;
+ return fs;
+ } finally {
+ try {
+ if(fis != null) fis.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
+ public long getInt(String key, int def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ public double getDouble(String key, double def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Double.parseDouble(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ public long getLong(String key, long def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Long.parseLong(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
}
Modified:
trunk/freenet/src/freenet/support/math/BootstrappingDecayingRunningAverage.java
===================================================================
---
trunk/freenet/src/freenet/support/math/BootstrappingDecayingRunningAverage.java
2006-08-12 20:55:25 UTC (rev 10050)
+++
trunk/freenet/src/freenet/support/math/BootstrappingDecayingRunningAverage.java
2006-08-12 21:21:43 UTC (rev 10051)
@@ -45,12 +45,19 @@
}
public BootstrappingDecayingRunningAverage(double defaultValue, double min,
- double max, int maxReports) {
+ double max, int maxReports, SimpleFieldSet fs) {
this.min = min;
this.max = max;
reports = 0;
currentValue = defaultValue;
this.maxReports = maxReports;
+ if(fs != null) {
+ currentValue = fs.getDouble("CurrentValue", currentValue);
+ reports = fs.getLong("Reports", reports);
+ zeros = fs.getLong("Zeros", zeros);
+ ones = fs.getLong("Ones", ones);
+ if(reports == 0) zeros = ones = 0;
+ }
}
public synchronized double currentValue() {