Store context in the PeerSelector so we don't have to pass it around

This commit is contained in:
zzz
2012-06-21 20:52:39 +00:00
parent 4e4634496a
commit 829e3f47ff
5 changed files with 50 additions and 28 deletions

View File

@ -15,8 +15,13 @@ import net.i2p.router.TunnelPoolSettings;
* *
*/ */
class ClientPeerSelector extends TunnelPeerSelector { class ClientPeerSelector extends TunnelPeerSelector {
public List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
int length = getLength(ctx, settings); public ClientPeerSelector(RouterContext context) {
super(context);
}
public List<Hash> selectPeers(TunnelPoolSettings settings) {
int length = getLength(settings);
if (length < 0) if (length < 0)
return null; return null;
if ( (length == 0) && (settings.getLength()+settings.getLengthVariance() > 0) ) if ( (length == 0) && (settings.getLength()+settings.getLengthVariance() > 0) )
@ -26,9 +31,9 @@ class ClientPeerSelector extends TunnelPeerSelector {
if (length > 0) { if (length > 0) {
if (shouldSelectExplicit(settings)) if (shouldSelectExplicit(settings))
return selectExplicit(ctx, settings, length); return selectExplicit(settings, length);
Set<Hash> exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory()); Set<Hash> exclude = getExclude(settings.isInbound(), false);
Set<Hash> matches = new HashSet(length); Set<Hash> matches = new HashSet(length);
if (length == 1) { if (length == 1) {
ctx.profileOrganizer().selectFastPeers(length, exclude, matches, 0); ctx.profileOrganizer().selectFastPeers(length, exclude, matches, 0);
@ -41,6 +46,9 @@ class ClientPeerSelector extends TunnelPeerSelector {
rv = new ArrayList(length + 1); rv = new ArrayList(length + 1);
// OBEP or IB last hop // OBEP or IB last hop
// group 0 or 1 if two hops, otherwise group 0 // group 0 or 1 if two hops, otherwise group 0
if (!settings.isInbound()) {
// exclude existing OBEPs to get some diversity
}
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 2 : 4); ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 2 : 4);
matches.remove(ctx.routerHash()); matches.remove(ctx.routerHash());
exclude.addAll(matches); exclude.addAll(matches);
@ -64,6 +72,9 @@ class ClientPeerSelector extends TunnelPeerSelector {
} }
// IBGW or OB first hop // IBGW or OB first hop
// group 2 or 3 if two hops, otherwise group 1 // group 2 or 3 if two hops, otherwise group 1
if (settings.isInbound()) {
// exclude existing IBGWs to get some diversity
}
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 3 : 5); ctx.profileOrganizer().selectFastPeers(1, exclude, matches, settings.getRandomKey(), length == 2 ? 3 : 5);
matches.remove(ctx.routerHash()); matches.remove(ctx.routerHash());
rv.addAll(matches); rv.addAll(matches);

View File

@ -18,9 +18,14 @@ import net.i2p.util.Log;
* *
*/ */
class ExploratoryPeerSelector extends TunnelPeerSelector { class ExploratoryPeerSelector extends TunnelPeerSelector {
public List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings) {
public ExploratoryPeerSelector(RouterContext context) {
super(context);
}
public List<Hash> selectPeers(TunnelPoolSettings settings) {
Log l = ctx.logManager().getLog(getClass()); Log l = ctx.logManager().getLog(getClass());
int length = getLength(ctx, settings); int length = getLength(settings);
if (length < 0) { if (length < 0) {
if (l.shouldLog(Log.DEBUG)) if (l.shouldLog(Log.DEBUG))
l.debug("Length requested is zero: " + settings); l.debug("Length requested is zero: " + settings);
@ -28,13 +33,13 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
} }
if (false && shouldSelectExplicit(settings)) { if (false && shouldSelectExplicit(settings)) {
List rv = selectExplicit(ctx, settings, length); List rv = selectExplicit(settings, length);
if (l.shouldLog(Log.DEBUG)) if (l.shouldLog(Log.DEBUG))
l.debug("Explicit peers selected: " + rv); l.debug("Explicit peers selected: " + rv);
return rv; return rv;
} }
Set<Hash> exclude = getExclude(ctx, settings.isInbound(), settings.isExploratory()); Set<Hash> exclude = getExclude(settings.isInbound(), true);
exclude.add(ctx.routerHash()); exclude.add(ctx.routerHash());
// Don't use ff peers for exploratory tunnels to lessen exposure to netDb searches and stores // Don't use ff peers for exploratory tunnels to lessen exposure to netDb searches and stores
// Hmm if they don't get explored they don't get a speed/capacity rating // Hmm if they don't get explored they don't get a speed/capacity rating
@ -42,7 +47,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
// FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb(); // FloodfillNetworkDatabaseFacade fac = (FloodfillNetworkDatabaseFacade)ctx.netDb();
// exclude.addAll(fac.getFloodfillPeers()); // exclude.addAll(fac.getFloodfillPeers());
HashSet matches = new HashSet(length); HashSet matches = new HashSet(length);
boolean exploreHighCap = shouldPickHighCap(ctx); boolean exploreHighCap = shouldPickHighCap();
// //
// We don't honor IP Restriction here, to be fixed // We don't honor IP Restriction here, to be fixed
@ -84,7 +89,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
* build success rate is much worse, return true so that reliability * build success rate is much worse, return true so that reliability
* is maintained. * is maintained.
*/ */
private static boolean shouldPickHighCap(RouterContext ctx) { private boolean shouldPickHighCap() {
if (ctx.getBooleanProperty("router.exploreHighCapacity")) if (ctx.getBooleanProperty("router.exploreHighCapacity"))
return true; return true;
@ -118,7 +123,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
if (ctx.router().getUptime() <= 11*60*1000) { if (ctx.router().getUptime() <= 11*60*1000) {
failPct = 100 - MIN_NONFAILING_PCT; failPct = 100 - MIN_NONFAILING_PCT;
} else { } else {
failPct = getExploratoryFailPercentage(ctx); failPct = getExploratoryFailPercentage();
//Log l = ctx.logManager().getLog(getClass()); //Log l = ctx.logManager().getLog(getClass());
//if (l.shouldLog(Log.DEBUG)) //if (l.shouldLog(Log.DEBUG))
// l.debug("Normalized Fail pct: " + failPct); // l.debug("Normalized Fail pct: " + failPct);
@ -140,9 +145,9 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
* Even this isn't the "true" rate for the NonFailingPeers pool, since we * Even this isn't the "true" rate for the NonFailingPeers pool, since we
* are often building exploratory tunnels using the HighCapacity pool. * are often building exploratory tunnels using the HighCapacity pool.
*/ */
private static int getExploratoryFailPercentage(RouterContext ctx) { private int getExploratoryFailPercentage() {
int c = getFailPercentage(ctx, "Client"); int c = getFailPercentage("Client");
int e = getFailPercentage(ctx, "Exploratory"); int e = getFailPercentage("Exploratory");
//Log l = ctx.logManager().getLog(getClass()); //Log l = ctx.logManager().getLog(getClass());
//if (l.shouldLog(Log.DEBUG)) //if (l.shouldLog(Log.DEBUG))
// l.debug("Client, Expl. Fail pct: " + c + ", " + e); // l.debug("Client, Expl. Fail pct: " + c + ", " + e);
@ -154,11 +159,11 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
return (100 * (e-c)) / (100-c); return (100 * (e-c)) / (100-c);
} }
private static int getFailPercentage(RouterContext ctx, String t) { private int getFailPercentage(String t) {
String pfx = "tunnel.build" + t; String pfx = "tunnel.build" + t;
int timeout = getEvents(ctx, pfx + "Expire", 10*60*1000); int timeout = getEvents(pfx + "Expire", 10*60*1000);
int reject = getEvents(ctx, pfx + "Reject", 10*60*1000); int reject = getEvents(pfx + "Reject", 10*60*1000);
int accept = getEvents(ctx, pfx + "Success", 10*60*1000); int accept = getEvents(pfx + "Success", 10*60*1000);
if (accept + reject + timeout <= 0) if (accept + reject + timeout <= 0)
return 0; return 0;
double pct = (double)(reject + timeout) / (accept + reject + timeout); double pct = (double)(reject + timeout) / (accept + reject + timeout);
@ -166,7 +171,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
} }
/** Use current + last to get more recent and smoother data */ /** Use current + last to get more recent and smoother data */
private static int getEvents(RouterContext ctx, String stat, long period) { private int getEvents(String stat, long period) {
RateStat rs = ctx.statManager().getRate(stat); RateStat rs = ctx.statManager().getRate(stat);
if (rs == null) if (rs == null)
return 0; return 0;

View File

@ -31,6 +31,12 @@ import net.i2p.util.VersionComparator;
* Todo: there's nothing non-static in here * Todo: there's nothing non-static in here
*/ */
public abstract class TunnelPeerSelector { public abstract class TunnelPeerSelector {
protected final RouterContext ctx;
protected TunnelPeerSelector(RouterContext context) {
ctx = context;
}
/** /**
* Which peers should go into the next tunnel for the given settings? * Which peers should go into the next tunnel for the given settings?
* *
@ -40,12 +46,12 @@ public abstract class TunnelPeerSelector {
* to build through, and the settings reject 0 hop tunnels, this will * to build through, and the settings reject 0 hop tunnels, this will
* return null. * return null.
*/ */
public abstract List<Hash> selectPeers(RouterContext ctx, TunnelPoolSettings settings); public abstract List<Hash> selectPeers(TunnelPoolSettings settings);
/** /**
* @return randomized number of hops 0-7, not including ourselves * @return randomized number of hops 0-7, not including ourselves
*/ */
protected int getLength(RouterContext ctx, TunnelPoolSettings settings) { protected int getLength(TunnelPoolSettings settings) {
int length = settings.getLength(); int length = settings.getLength();
int override = settings.getLengthOverride(); int override = settings.getLengthOverride();
if (override >= 0) { if (override >= 0) {
@ -109,7 +115,7 @@ public abstract class TunnelPeerSelector {
* Needs analysis and testing * Needs analysis and testing
* @return should always be false * @return should always be false
*/ */
protected List<Hash> selectExplicit(RouterContext ctx, TunnelPoolSettings settings, int length) { protected List<Hash> selectExplicit(TunnelPoolSettings settings, int length) {
String peers = null; String peers = null;
Properties opts = settings.getUnknownOptions(); Properties opts = settings.getUnknownOptions();
if (opts != null) if (opts != null)
@ -173,7 +179,7 @@ public abstract class TunnelPeerSelector {
/** /**
* Pick peers that we want to avoid * Pick peers that we want to avoid
*/ */
public Set<Hash> getExclude(RouterContext ctx, boolean isInbound, boolean isExploratory) { public Set<Hash> getExclude(boolean isInbound, boolean isExploratory) {
// we may want to update this to skip 'hidden' or 'unreachable' peers, but that // we may want to update this to skip 'hidden' or 'unreachable' peers, but that
// isn't safe, since they may publish one set of routerInfo to us and another to // isn't safe, since they may publish one set of routerInfo to us and another to
// other peers. the defaults for filterUnreachable has always been to return false, // other peers. the defaults for filterUnreachable has always been to return false,
@ -196,7 +202,7 @@ public abstract class TunnelPeerSelector {
peers.addAll(ctx.profileOrganizer().selectPeersRecentlyRejecting()); peers.addAll(ctx.profileOrganizer().selectPeersRecentlyRejecting());
peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels()); peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels());
// if (false && filterUnreachable(ctx, isInbound, isExploratory)) { // if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
if (filterUnreachable(ctx, isInbound, isExploratory)) { if (filterUnreachable(isInbound, isExploratory)) {
// NOTE: filterUnreachable returns true for inbound, false for outbound // NOTE: filterUnreachable returns true for inbound, false for outbound
// This is the only use for getPeersByCapability? And the whole set of datastructures in PeerManager? // This is the only use for getPeersByCapability? And the whole set of datastructures in PeerManager?
Collection<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE); Collection<Hash> caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
@ -439,7 +445,7 @@ public abstract class TunnelPeerSelector {
* do we want to skip peers who haven't been up for long? * do we want to skip peers who haven't been up for long?
* @return true for inbound, false for outbound, unless configured otherwise * @return true for inbound, false for outbound, unless configured otherwise
*/ */
protected boolean filterUnreachable(RouterContext ctx, boolean isInbound, boolean isExploratory) { protected boolean filterUnreachable(boolean isInbound, boolean isExploratory) {
boolean def = false; boolean def = false;
String val = null; String val = null;

View File

@ -1093,7 +1093,7 @@ public class TunnelPool {
} }
if (peers == null) { if (peers == null) {
setLengthOverride(); setLengthOverride();
peers = _peerSelector.selectPeers(_context, settings); peers = _peerSelector.selectPeers(settings);
} }
if ( (peers == null) || (peers.isEmpty()) ) { if ( (peers == null) || (peers.isEmpty()) ) {

View File

@ -61,7 +61,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
_clientInboundPools = new ConcurrentHashMap(4); _clientInboundPools = new ConcurrentHashMap(4);
_clientOutboundPools = new ConcurrentHashMap(4); _clientOutboundPools = new ConcurrentHashMap(4);
_clientPeerSelector = new ClientPeerSelector(); _clientPeerSelector = new ClientPeerSelector(ctx);
_executor = new BuildExecutor(ctx, this); _executor = new BuildExecutor(ctx, this);
I2PThread execThread = new I2PThread(_executor, "BuildExecutor", true); I2PThread execThread = new I2PThread(_executor, "BuildExecutor", true);
@ -511,7 +511,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
t.setDaemon(true); t.setDaemon(true);
t.start(); t.start();
} }
ExploratoryPeerSelector selector = new ExploratoryPeerSelector(); ExploratoryPeerSelector selector = new ExploratoryPeerSelector(_context);
TunnelPoolSettings inboundSettings = new TunnelPoolSettings(); TunnelPoolSettings inboundSettings = new TunnelPoolSettings();
inboundSettings.setIsExploratory(true); inboundSettings.setIsExploratory(true);