forked from I2P_Developers/i2p.i2p
NetDB: Publish RI faster when costs change (ticket #1437)
PLRIJ interval was 37-50 minutes. Reduce that by 4x, but for 3 out of 4 times, only publish if something changes, including cost. 4th time, always publish, as before. This will hopefully reduce routers getting slammed to conn limits on a transport.
This commit is contained in:
15
history.txt
15
history.txt
@@ -1,9 +1,20 @@
|
|||||||
|
2015-01-09 zzz
|
||||||
|
* NetDB: Publish RI faster when costs change (ticket #1437)
|
||||||
|
|
||||||
|
2015-01-08 zzz
|
||||||
|
* Console, i2ptunnel, proxy: Renaming of various things to "hidden services"
|
||||||
|
|
||||||
2015-01-07 zzz
|
2015-01-07 zzz
|
||||||
* ClientAppConfig: Start i2ptunnel sooner (ticket #1162)
|
* ClientAppConfig: Start i2ptunnel sooner (ticket #1162)
|
||||||
* NetDB: Possible fixes for reseed completion not recognized (ticket #1384)
|
* NetDB: Possible fixes for reseed completion not recognized (ticket #1384)
|
||||||
* Router: Add startup/shutdown state machine
|
* Router:
|
||||||
|
- Add startup/shutdown state machine
|
||||||
|
- Don't reset uptime after a soft restart
|
||||||
* Startup: Accept tunnels after 10 minutes instead of 20 (ticket #1152)
|
* Startup: Accept tunnels after 10 minutes instead of 20 (ticket #1152)
|
||||||
* Tunnels: Cleanup, catch more cases of zero-hop configuration
|
* Tunnels:
|
||||||
|
- Cleanup, catch more cases of zero-hop configuration
|
||||||
|
- Temporarily increase exploratory tunnel quantity at startup,
|
||||||
|
so that netdb refresh will work better
|
||||||
|
|
||||||
2015-01-05 zzz
|
2015-01-05 zzz
|
||||||
* Blocklist:
|
* Blocklist:
|
||||||
|
@@ -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 = 9;
|
public final static long BUILD = 10;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
@@ -8,10 +8,17 @@ package net.i2p.router.networkdb;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
|
import net.i2p.data.router.RouterAddress;
|
||||||
import net.i2p.data.router.RouterInfo;
|
import net.i2p.data.router.RouterInfo;
|
||||||
import net.i2p.data.SigningPrivateKey;
|
import net.i2p.data.SigningPrivateKey;
|
||||||
import net.i2p.router.JobImpl;
|
import net.i2p.router.JobImpl;
|
||||||
@@ -30,15 +37,16 @@ public class PublishLocalRouterInfoJob extends JobImpl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Don't store if somebody else stored it recently.
|
* Don't store if somebody else stored it recently.
|
||||||
|
* Must be less than PUBLISH_DELAY * 3 / 16 (see getDelay())
|
||||||
*/
|
*/
|
||||||
private static final long MIN_PUBLISH_DELAY = 25*60*1000;
|
private static final long MIN_PUBLISH_DELAY = 9*60*1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Too short and the network puts a big connection load on the
|
* Too short and the network puts a big connection load on the
|
||||||
* floodfills since we store directly.
|
* floodfills since we store directly.
|
||||||
* Too long and the floodfill will drop us - timeout is 60 minutes.
|
* Too long and the floodfill will drop us - timeout is 60 minutes.
|
||||||
*/
|
*/
|
||||||
private static final long PUBLISH_DELAY = MIN_PUBLISH_DELAY * 2;
|
private static final long PUBLISH_DELAY = 52*60*1000;
|
||||||
|
|
||||||
/** this needs to be long enough to give us time to start up,
|
/** this needs to be long enough to give us time to start up,
|
||||||
but less than 20m (when we start accepting tunnels and could be a IBGW)
|
but less than 20m (when we start accepting tunnels and could be a IBGW)
|
||||||
@@ -47,7 +55,8 @@ public class PublishLocalRouterInfoJob extends JobImpl {
|
|||||||
we can't build IB exploratory tunnels.
|
we can't build IB exploratory tunnels.
|
||||||
*/
|
*/
|
||||||
private static final long FIRST_TIME_DELAY = 90*1000;
|
private static final long FIRST_TIME_DELAY = 90*1000;
|
||||||
boolean _notFirstTime;
|
private volatile boolean _notFirstTime;
|
||||||
|
private final AtomicInteger _runCount = new AtomicInteger();
|
||||||
|
|
||||||
public PublishLocalRouterInfoJob(RouterContext ctx) {
|
public PublishLocalRouterInfoJob(RouterContext ctx) {
|
||||||
super(ctx);
|
super(ctx);
|
||||||
@@ -55,6 +64,7 @@ public class PublishLocalRouterInfoJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName() { return "Publish Local Router Info"; }
|
public String getName() { return "Publish Local Router Info"; }
|
||||||
|
|
||||||
public void runJob() {
|
public void runJob() {
|
||||||
long last = getContext().netDb().getLastRouterInfoPublishTime();
|
long last = getContext().netDb().getLastRouterInfoPublishTime();
|
||||||
long now = getContext().clock().now();
|
long now = getContext().clock().now();
|
||||||
@@ -63,16 +73,45 @@ public class PublishLocalRouterInfoJob extends JobImpl {
|
|||||||
requeue(last + delay - now);
|
requeue(last + delay - now);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RouterInfo ri = new RouterInfo(getContext().router().getRouterInfo());
|
RouterInfo oldRI = getContext().router().getRouterInfo();
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Old routerInfo contains " + ri.getAddresses().size()
|
_log.debug("Old routerInfo contains " + oldRI.getAddresses().size()
|
||||||
+ " addresses and " + ri.getOptionsMap().size() + " options");
|
+ " addresses and " + oldRI.getOptionsMap().size() + " options");
|
||||||
Properties stats = getContext().statPublisher().publishStatistics();
|
|
||||||
stats.setProperty(RouterInfo.PROP_NETWORK_ID, ""+Router.NETWORK_ID);
|
|
||||||
try {
|
try {
|
||||||
|
List<RouterAddress> oldAddrs = new ArrayList(oldRI.getAddresses());
|
||||||
|
List<RouterAddress> newAddrs = getContext().commSystem().createAddresses();
|
||||||
|
int count = _runCount.incrementAndGet();
|
||||||
|
if (_notFirstTime && (count % 4) != 0 && oldAddrs.size() == newAddrs.size()) {
|
||||||
|
// 3 times out of 4, we don't republish if everything is the same...
|
||||||
|
// If something changed, including the cost, then publish,
|
||||||
|
// otherwise don't.
|
||||||
|
boolean different = false;
|
||||||
|
Comparator<RouterAddress> comp = new AddrComparator();
|
||||||
|
Collections.sort(oldAddrs, comp);
|
||||||
|
Collections.sort(newAddrs, comp);
|
||||||
|
for (int i = 0; i < oldAddrs.size(); i++) {
|
||||||
|
// deepEquals() includes cost
|
||||||
|
if (!oldAddrs.get(i).deepEquals(newAddrs.get(i))) {
|
||||||
|
different = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!different) {
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Not republishing early because costs are the same");
|
||||||
|
requeue(getDelay());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Republishing early because addresses or costs have changed - old:\n" +
|
||||||
|
oldAddrs + "\nnew:\n" + newAddrs);
|
||||||
|
}
|
||||||
|
RouterInfo ri = new RouterInfo(oldRI);
|
||||||
ri.setPublished(getContext().clock().now());
|
ri.setPublished(getContext().clock().now());
|
||||||
|
Properties stats = getContext().statPublisher().publishStatistics();
|
||||||
|
stats.setProperty(RouterInfo.PROP_NETWORK_ID, ""+Router.NETWORK_ID);
|
||||||
ri.setOptions(stats);
|
ri.setOptions(stats);
|
||||||
ri.setAddresses(getContext().commSystem().createAddresses());
|
ri.setAddresses(newAddrs);
|
||||||
|
|
||||||
getContext().router().addCapabilities(ri);
|
getContext().router().addCapabilities(ri);
|
||||||
SigningPrivateKey key = getContext().keyManager().getSigningPrivateKey();
|
SigningPrivateKey key = getContext().keyManager().getSigningPrivateKey();
|
||||||
@@ -98,8 +137,7 @@ public class PublishLocalRouterInfoJob extends JobImpl {
|
|||||||
_log.error("Error signing the updated local router info!", dfe);
|
_log.error("Error signing the updated local router info!", dfe);
|
||||||
}
|
}
|
||||||
if (_notFirstTime) {
|
if (_notFirstTime) {
|
||||||
long delay = getDelay();
|
requeue(getDelay());
|
||||||
requeue(delay);
|
|
||||||
} else {
|
} else {
|
||||||
requeue(FIRST_TIME_DELAY);
|
requeue(FIRST_TIME_DELAY);
|
||||||
_notFirstTime = true;
|
_notFirstTime = true;
|
||||||
@@ -107,6 +145,29 @@ public class PublishLocalRouterInfoJob extends JobImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long getDelay() {
|
private long getDelay() {
|
||||||
return (PUBLISH_DELAY * 3 / 4) + getContext().random().nextLong(PUBLISH_DELAY / 4);
|
long rv = (PUBLISH_DELAY * 3 / 4) + getContext().random().nextLong(PUBLISH_DELAY / 4);
|
||||||
|
// run 4x as often as usual publish time (see above)
|
||||||
|
rv /= 4;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arbitrary sort so we can attempt to compare costs between two RIs to see if they have changed
|
||||||
|
*
|
||||||
|
* @since 0.9.18
|
||||||
|
*/
|
||||||
|
private static class AddrComparator implements Comparator<RouterAddress>, Serializable {
|
||||||
|
public int compare(RouterAddress l, RouterAddress r) {
|
||||||
|
int c = l.getTransportStyle().compareTo(r.getTransportStyle());
|
||||||
|
if (c != 0)
|
||||||
|
return c;
|
||||||
|
String lh = l.getHost();
|
||||||
|
String rh = r.getHost();
|
||||||
|
if (lh == null)
|
||||||
|
return rh == null ? 0 : -1;
|
||||||
|
if (rh == null)
|
||||||
|
return 1;
|
||||||
|
return lh.compareTo(rh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user