2005-02-24 jrandom
* Throttle the number of tunnel rebuilds per minute, preventing CPU overload under catastrophic failures (thanks Tracker and cervantes!) * Block the router startup process until we've initialized the clock
This commit is contained in:
@ -101,6 +101,15 @@ public class Timestamper implements Runnable {
|
||||
t.start();
|
||||
}
|
||||
|
||||
public void waitForInitialization() {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (!_initialized)
|
||||
wait();
|
||||
}
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
_log = _context.logManager().getLog(Timestamper.class);
|
||||
@ -130,6 +139,9 @@ public class Timestamper implements Runnable {
|
||||
lastFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
synchronized (this) { notifyAll(); }
|
||||
long sleepTime = _context.random().nextInt(_queryFrequency) + _queryFrequency;
|
||||
if (lastFailed)
|
||||
sleepTime = 30*1000;
|
||||
@ -137,6 +149,7 @@ public class Timestamper implements Runnable {
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
_log.log(Log.CRIT, "Timestamper died!", t);
|
||||
synchronized (this) { notifyAll(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,9 @@
|
||||
$Id: history.txt,v 1.155 2005/02/23 16:44:32 jrandom Exp $
|
||||
$Id: history.txt,v 1.156 2005/02/24 13:05:26 jrandom Exp $
|
||||
|
||||
2005-02-24 jrandom
|
||||
* Throttle the number of tunnel rebuilds per minute, preventing CPU
|
||||
overload under catastrophic failures (thanks Tracker and cervantes!)
|
||||
* Block the router startup process until we've initialized the clock
|
||||
|
||||
2005-02-24 jrandom
|
||||
* Cache temporary memory allocation in the DSA's SHA1 impl, and the packet
|
||||
|
@ -225,6 +225,14 @@ public class Router {
|
||||
warmupCrypto();
|
||||
_sessionKeyPersistenceHelper.startup();
|
||||
//_context.adminManager().startup();
|
||||
|
||||
// let the timestamper get us sync'ed
|
||||
long before = System.currentTimeMillis();
|
||||
_context.clock().getTimestamper().waitForInitialization();
|
||||
long waited = System.currentTimeMillis() - before;
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Waited " + waited + "ms to initialize");
|
||||
|
||||
_context.jobQueue().addJob(new StartupJob(_context));
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
||||
*
|
||||
*/
|
||||
public class RouterVersion {
|
||||
public final static String ID = "$Revision: 1.150 $ $Date: 2005/02/23 16:44:32 $";
|
||||
public final static String ID = "$Revision: 1.151 $ $Date: 2005/02/24 13:05:26 $";
|
||||
public final static String VERSION = "0.5.0.1";
|
||||
public final static long BUILD = 2;
|
||||
public final static long BUILD = 3;
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Router version: " + VERSION);
|
||||
System.out.println("Router ID: " + RouterVersion.ID);
|
||||
|
@ -11,6 +11,7 @@ import net.i2p.data.Lease;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.TunnelId;
|
||||
|
||||
import net.i2p.router.JobImpl;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.router.TunnelInfo;
|
||||
@ -29,6 +30,16 @@ public class TunnelPool {
|
||||
private TunnelPoolManager _manager;
|
||||
private boolean _alive;
|
||||
private long _lifetimeProcessed;
|
||||
private int _buildsThisMinute;
|
||||
private long _currentMinute;
|
||||
private RefreshJob _refreshJob;
|
||||
|
||||
/**
|
||||
* Only 3 builds per minute per pool, even if we have failing tunnels,
|
||||
* etc. On overflow, the necessary additional tunnels are built by the
|
||||
* RefreshJob
|
||||
*/
|
||||
private static final int MAX_BUILDS_PER_MINUTE = 3;
|
||||
|
||||
public TunnelPool(RouterContext ctx, TunnelPoolManager mgr, TunnelPoolSettings settings, TunnelPeerSelector sel, TunnelBuilder builder) {
|
||||
_context = ctx;
|
||||
@ -40,11 +51,16 @@ public class TunnelPool {
|
||||
_builder = builder;
|
||||
_alive = false;
|
||||
_lifetimeProcessed = 0;
|
||||
_buildsThisMinute = 0;
|
||||
_currentMinute = ctx.clock().now();
|
||||
_refreshJob = new RefreshJob(ctx);
|
||||
refreshSettings();
|
||||
}
|
||||
|
||||
public void startup() {
|
||||
_alive = true;
|
||||
_refreshJob.getTiming().setStartAfter(_context.clock().now() + 60*1000);
|
||||
_context.jobQueue().addJob(_refreshJob);
|
||||
int added = refreshBuilders();
|
||||
if (added <= 0) {
|
||||
// we just reconnected and didn't require any new tunnel builders.
|
||||
@ -92,10 +108,26 @@ public class TunnelPool {
|
||||
_log.info(toString() + ": refreshing builders, previously had " + usableTunnels
|
||||
+ ", want a total of " + target + ", creating "
|
||||
+ (target-usableTunnels) + " new ones.");
|
||||
for (int i = usableTunnels; i < target; i++)
|
||||
_builder.buildTunnel(_context, this);
|
||||
|
||||
return (target > usableTunnels ? target-usableTunnels : 0);
|
||||
|
||||
if (target > usableTunnels) {
|
||||
long minute = _context.clock().now();
|
||||
minute = minute - (minute % 60*1000);
|
||||
if (_currentMinute < minute) {
|
||||
_currentMinute = minute;
|
||||
_buildsThisMinute = 0;
|
||||
}
|
||||
int build = (target - usableTunnels);
|
||||
if (build > (MAX_BUILDS_PER_MINUTE - _buildsThisMinute))
|
||||
build = (MAX_BUILDS_PER_MINUTE - _buildsThisMinute);
|
||||
|
||||
for (int i = 0; i < build; i++)
|
||||
_builder.buildTunnel(_context, this);
|
||||
_buildsThisMinute += build;
|
||||
|
||||
return build;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void refreshSettings() {
|
||||
@ -386,4 +418,23 @@ public class TunnelPool {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* We choke the # of rebuilds per pool per minute, so we need this to
|
||||
* make sure to build enough tunnels.
|
||||
*
|
||||
*/
|
||||
private class RefreshJob extends JobImpl {
|
||||
public RefreshJob(RouterContext ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
public String getName() { return "Refresh pool"; }
|
||||
public void runJob() {
|
||||
if (!_alive) return;
|
||||
int added = refreshBuilders();
|
||||
if ( (added > 0) && (_log.shouldLog(Log.WARN)) )
|
||||
_log.warn("Passive rebuilding a tunnel");
|
||||
requeue(60*1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user