- Implement automatic reseeding (ticket #521)
   - Increase minimum routers from 15 to 50
This commit is contained in:
zzz
2012-11-16 14:47:55 +00:00
parent 6902a8392f
commit ae6dad6e48
5 changed files with 49 additions and 18 deletions

View File

@ -1,3 +1,10 @@
2012-11-16 zzz
* i2psnark: Fix rare IOOBE (ticket #777)
* NetDB:
- Implement automatic reseeding (ticket #521)
- Increase minimum routers
* Tunnels: Fix outbound tunnel message priority (ticket #719)
2012-11-13 zzz 2012-11-13 zzz
* Bandwidth Limiter: Fix stats broken in -1 * Bandwidth Limiter: Fix stats broken in -1
* HTTP Proxy: Store referrer of new addresses in address book * HTTP Proxy: Store referrer of new addresses in address book

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 6; public final static long BUILD = 7;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@ -105,10 +105,17 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
public final static String PROP_DB_DIR = "router.networkDatabase.dbDir"; public final static String PROP_DB_DIR = "router.networkDatabase.dbDir";
public final static String DEFAULT_DB_DIR = "netDb"; public final static String DEFAULT_DB_DIR = "netDb";
/** Reseed if below this.
* @since 0.9.4
*/
static final int MIN_RESEED = ReseedChecker.MINIMUM;
/** if we have less than this many routers left, don't drop any more, /** if we have less than this many routers left, don't drop any more,
* even if they're failing or doing bad stuff. * even if they're failing or doing bad stuff.
* As of 0.9.4, we make this LOWER than the min for reseeding, so
* a reseed will be forced if necessary.
*/ */
protected final static int MIN_REMAINING_ROUTERS = 25; protected final static int MIN_REMAINING_ROUTERS = MIN_RESEED - 10;
/** /**
* limits for accepting a dbDtore of a router (unless we dont * limits for accepting a dbDtore of a router (unless we dont

View File

@ -46,9 +46,9 @@ class PersistentDataStore extends TransientDataStore {
private final KademliaNetworkDatabaseFacade _facade; private final KademliaNetworkDatabaseFacade _facade;
private final Writer _writer; private final Writer _writer;
private final ReadJob _readJob; private final ReadJob _readJob;
private boolean _initialized; private volatile boolean _initialized;
private final static int READ_DELAY = 60*1000; private final static int READ_DELAY = 2*60*1000;
/** /**
* @param dbDir relative path * @param dbDir relative path
@ -319,14 +319,21 @@ class PersistentDataStore extends TransientDataStore {
return data.getDate(); return data.getDate();
} }
/** This is only for manual reseeding? Why bother every 60 sec??? */ /**
* This is mostly for manual reseeding, i.e. the user manually
* copies RI files to the directory. Nobody does this,
* so this is run way too often.
* Reseed task calls wakeup() on completion.
* As of 0.9.4, also initiates an automatic reseed if necessary.
*/
private class ReadJob extends JobImpl { private class ReadJob extends JobImpl {
private boolean _alreadyWarned;
private long _lastModified; private long _lastModified;
private long _lastReseed;
private static final int MIN_ROUTERS = KademliaNetworkDatabaseFacade.MIN_RESEED;
private static final long MIN_RESEED_INTERVAL = 90*60*1000;
public ReadJob() { public ReadJob() {
super(PersistentDataStore.this._context); super(PersistentDataStore.this._context);
_alreadyWarned = false;
} }
public String getName() { return "DB Read Job"; } public String getName() { return "DB Read Job"; }
@ -334,7 +341,8 @@ class PersistentDataStore extends TransientDataStore {
public void runJob() { public void runJob() {
// check directory mod time to save a lot of object churn in scanning all the file names // check directory mod time to save a lot of object churn in scanning all the file names
long lastMod = _dbDir.lastModified(); long lastMod = _dbDir.lastModified();
if (lastMod > _lastModified) { // if size() (= RI + LS) is too low, call anyway to check for reseed
if (lastMod > _lastModified || size() < MIN_ROUTERS + 10) {
_lastModified = lastMod; _lastModified = lastMod;
_log.info("Rereading new files"); _log.info("Rereading new files");
// synch with the writer job // synch with the writer job
@ -354,9 +362,7 @@ class PersistentDataStore extends TransientDataStore {
File routerInfoFiles[] = _dbDir.listFiles(RouterInfoFilter.getInstance()); File routerInfoFiles[] = _dbDir.listFiles(RouterInfoFilter.getInstance());
if (routerInfoFiles != null) { if (routerInfoFiles != null) {
routerCount += routerInfoFiles.length; routerCount = routerInfoFiles.length;
if (routerInfoFiles.length > 5)
_alreadyWarned = false;
for (int i = 0; i < routerInfoFiles.length; i++) { for (int i = 0; i < routerInfoFiles.length; i++) {
// drop out if the router gets killed right after startup // drop out if the router gets killed right after startup
if (!_context.router().isAlive()) if (!_context.router().isAlive())
@ -373,10 +379,16 @@ class PersistentDataStore extends TransientDataStore {
} }
} }
if (!_alreadyWarned) { if (!_initialized) {
_facade.reseedChecker().checkReseed(routerCount); if (_facade.reseedChecker().checkReseed(routerCount))
_alreadyWarned = true; _lastReseed = _context.clock().now();
_initialized = true; _initialized = true;
} else if (_lastReseed < _context.clock().now() - MIN_RESEED_INTERVAL) {
int count = Math.min(routerCount, size());
if (count < MIN_ROUTERS) {
if (_facade.reseedChecker().checkReseed(count))
_lastReseed = _context.clock().now();
}
} }
} }
} }

View File

@ -4,6 +4,7 @@ import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.util.Addresses;
import net.i2p.util.Log; import net.i2p.util.Log;
/** /**
@ -23,10 +24,10 @@ public class ReseedChecker {
private final RouterContext _context; private final RouterContext _context;
private final Log _log; private final Log _log;
private final AtomicBoolean _inProgress = new AtomicBoolean(); private final AtomicBoolean _inProgress = new AtomicBoolean();
private String _lastStatus = ""; private volatile String _lastStatus = "";
private String _lastError = ""; private volatile String _lastError = "";
private static final int MINIMUM = 15; public static final int MINIMUM = 50;
/** /**
* All reseeding must be done through this instance. * All reseeding must be done through this instance.
@ -64,6 +65,10 @@ public class ReseedChecker {
File noReseedFileAlt2 = new File(_context.getConfigDir(), ".i2pnoreseed"); File noReseedFileAlt2 = new File(_context.getConfigDir(), ".i2pnoreseed");
File noReseedFileAlt3 = new File(_context.getConfigDir(), "noreseed.i2p"); File noReseedFileAlt3 = new File(_context.getConfigDir(), "noreseed.i2p");
if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) {
if (!Addresses.isConnected()) {
_log.logAlways(Log.WARN, "Cannot reseed, no network connection");
return false;
}
if (count <= 1) if (count <= 1)
_log.logAlways(Log.INFO, "Downloading peer router information for a new I2P installation"); _log.logAlways(Log.INFO, "Downloading peer router information for a new I2P installation");
else else
@ -96,7 +101,7 @@ public class ReseedChecker {
} }
} else { } else {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Reseed already in prgress"); _log.warn("Reseed already in progress");
return false; return false;
} }
} }