forked from I2P_Developers/i2p.i2p
Profiles:
- Remove unused calculators and RateStats: CapacityCalculator, StrictSpeedCalculator, IsFailingCalculator; sendFailureSize, processSuccessRate, processfailureRate, commErrorRate, tunnelTestResponseTimeSlow - Reduced number of Rates in these RateStats: sendSuccessSize, receiveSize, rejectRate, failRate - ~5KB/profile savings total - Deflate speed calculation once an hour instead of once a day, to improve fast tier selection
This commit is contained in:
@@ -16,9 +16,7 @@ import net.i2p.router.peermanager.IsFailingCalculator;
|
||||
import net.i2p.router.peermanager.PeerManagerFacadeImpl;
|
||||
import net.i2p.router.peermanager.ProfileManagerImpl;
|
||||
import net.i2p.router.peermanager.ProfileOrganizer;
|
||||
import net.i2p.router.peermanager.ReliabilityCalculator;
|
||||
import net.i2p.router.peermanager.SpeedCalculator;
|
||||
import net.i2p.router.peermanager.StrictSpeedCalculator;
|
||||
import net.i2p.router.transport.CommSystemFacadeImpl;
|
||||
import net.i2p.router.transport.FIFOBandwidthLimiter;
|
||||
import net.i2p.router.transport.OutboundMessageRegistry;
|
||||
@@ -65,9 +63,7 @@ public class RouterContext extends I2PAppContext {
|
||||
private Calculator _isFailingCalc;
|
||||
private Calculator _integrationCalc;
|
||||
private Calculator _speedCalc;
|
||||
private Calculator _reliabilityCalc;
|
||||
private Calculator _capacityCalc;
|
||||
private Calculator _oldSpeedCalc;
|
||||
|
||||
|
||||
private static List _contexts = new ArrayList(1);
|
||||
@@ -135,8 +131,6 @@ public class RouterContext extends I2PAppContext {
|
||||
_isFailingCalc = new IsFailingCalculator(this);
|
||||
_integrationCalc = new IntegrationCalculator(this);
|
||||
_speedCalc = new SpeedCalculator(this);
|
||||
_oldSpeedCalc = new StrictSpeedCalculator(this);
|
||||
_reliabilityCalc = new ReliabilityCalculator(this);
|
||||
_capacityCalc = new CapacityCalculator(this);
|
||||
}
|
||||
|
||||
@@ -270,9 +264,6 @@ public class RouterContext extends I2PAppContext {
|
||||
public Calculator integrationCalculator() { return _integrationCalc; }
|
||||
/** how do we rank the speed of profiles? */
|
||||
public Calculator speedCalculator() { return _speedCalc; }
|
||||
public Calculator oldSpeedCalculator() { return _oldSpeedCalc; }
|
||||
/** how do we rank the reliability of profiles? */
|
||||
public Calculator reliabilityCalculator() { return _reliabilityCalc; }
|
||||
/** how do we rank the capacity of profiles? */
|
||||
public Calculator capacityCalculator() { return _capacityCalc; }
|
||||
|
||||
@@ -301,7 +292,6 @@ public class RouterContext extends I2PAppContext {
|
||||
buf.append(_isFailingCalc).append('\n');
|
||||
buf.append(_integrationCalc).append('\n');
|
||||
buf.append(_speedCalc).append('\n');
|
||||
buf.append(_reliabilityCalc).append('\n');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
@@ -1,82 +0,0 @@
|
||||
package net.i2p.router.peermanager;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Simple boolean calculation to determine whether the given profile is "failing" -
|
||||
* meaning we shouldn't bother trying to get them to do something. However, if we
|
||||
* have a specific need to contact them in particular - e.g. instructions in a garlic
|
||||
* or leaseSet - we will try. The currently implemented algorithm determines that
|
||||
* a profile is failing if withing the last few minutes, they've done something bad: <ul>
|
||||
* <li>It has a comm error (TCP disconnect, etc) in the last minute or two</li>
|
||||
* <li>They've failed to respond to a db message in the last minute or two</li>
|
||||
* <li>They've rejected a tunnel in the last 5 minutes</li>
|
||||
* <li>They've been unreachable any time in the last 5 minutes</li>
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
public class IsFailingCalculator extends Calculator {
|
||||
private Log _log;
|
||||
private RouterContext _context;
|
||||
|
||||
/** if they haven't b0rked in the last 2 minutes, they're ok */
|
||||
private final static long GRACE_PERIOD = 2*60*1000;
|
||||
|
||||
public IsFailingCalculator(RouterContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(IsFailingCalculator.class);
|
||||
}
|
||||
|
||||
public boolean calcBoolean(PeerProfile profile) {
|
||||
// have we failed in the last 119 seconds?
|
||||
/*
|
||||
if ( (profile.getCommError().getRate(60*1000).getCurrentEventCount() > 0) ||
|
||||
(profile.getCommError().getRate(60*1000).getLastEventCount() > 0) ||
|
||||
(profile.getCommError().getRate(10*60*1000).getCurrentEventCount() > 0) ) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Peer " + profile.getPeer().toBase64()
|
||||
+ " is failing because it had a comm error recently ");
|
||||
return true;
|
||||
} else {
|
||||
*/
|
||||
//if ( (profile.getDBHistory().getFailedLookupRate().getRate(60*1000).getCurrentEventCount() > 0) ||
|
||||
// (profile.getDBHistory().getFailedLookupRate().getRate(60*1000).getLastEventCount() > 0) ) {
|
||||
// // are they overloaded (or disconnected)?
|
||||
// return true;
|
||||
//}
|
||||
|
||||
// this doesn't make sense with probabalistic rejections - we should be
|
||||
// adequately dampening the capacity so these peers aren't queried
|
||||
|
||||
//Rate rejectRate = profile.getTunnelHistory().getRejectionRate().getRate(10*60*1000);
|
||||
//if (rejectRate.getCurrentEventCount() >= 2) {
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Peer " + profile.getPeer().toBase64()
|
||||
// + " is failing because they rejected some tunnels recently");
|
||||
// return true;
|
||||
//}
|
||||
|
||||
////
|
||||
// the right way to behave would be to use some statistical
|
||||
// analysis on the failure rate, and only mark the peer as failing
|
||||
// if their rate exceeded the expected rate (mean, median, stddev, etc)
|
||||
////
|
||||
|
||||
//Rate failedRate = profile.getTunnelHistory().getFailedRate().getRate(60*1000);
|
||||
//if (failedRate.getCurrentEventCount() >= 2) {
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Peer " + profile.getPeer().toBase64()
|
||||
// + " is failing because too many of their tunnels failed recently");
|
||||
// return true;
|
||||
//}
|
||||
|
||||
// if they have rejected us saying they're totally broken anytime in the last
|
||||
// 10 minutes, dont bother 'em
|
||||
if (profile.getTunnelHistory().getLastRejectedCritical() > _context.clock().now() - 10*60*1000)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
//}
|
||||
}
|
||||
}
|
@@ -37,25 +37,19 @@ public class PeerProfile {
|
||||
private double _tunnelTestResponseTimeAvg;
|
||||
// periodic rates
|
||||
private RateStat _sendSuccessSize = null;
|
||||
private RateStat _sendFailureSize = null;
|
||||
private RateStat _receiveSize = null;
|
||||
private RateStat _dbResponseTime = null;
|
||||
private RateStat _tunnelCreateResponseTime = null;
|
||||
private RateStat _tunnelTestResponseTime = null;
|
||||
private RateStat _tunnelTestResponseTimeSlow = null;
|
||||
private RateStat _commError = null;
|
||||
private RateStat _dbIntroduction = null;
|
||||
// calculation bonuses
|
||||
private long _speedBonus;
|
||||
private long _reliabilityBonus;
|
||||
private long _capacityBonus;
|
||||
private long _integrationBonus;
|
||||
// calculation values
|
||||
private double _speedValue;
|
||||
private double _reliabilityValue;
|
||||
private double _capacityValue;
|
||||
private double _integrationValue;
|
||||
private double _oldSpeedValue;
|
||||
private boolean _isFailing;
|
||||
// good vs bad behavior
|
||||
private TunnelHistory _tunnelHistory;
|
||||
@@ -72,7 +66,6 @@ public class PeerProfile {
|
||||
_log = context.logManager().getLog(PeerProfile.class);
|
||||
_expanded = false;
|
||||
_speedValue = 0;
|
||||
_reliabilityValue = 0;
|
||||
_capacityValue = 0;
|
||||
_integrationValue = 0;
|
||||
_isFailing = false;
|
||||
@@ -111,6 +104,11 @@ public class PeerProfile {
|
||||
* given period?)
|
||||
* Also mark active if it is connected, as this will tend to encourage use
|
||||
* of already-connected peers.
|
||||
*
|
||||
* Note: this appears to be the only use for these two RateStats.
|
||||
*
|
||||
* @param period must be one of the periods in the RateStat constructors below
|
||||
* (5*60*1000 or 60*60*1000)
|
||||
*/
|
||||
public boolean getIsActive(long period) {
|
||||
if ( (getSendSuccessSize().getRate(period).getCurrentEventCount() > 0) ||
|
||||
@@ -154,8 +152,6 @@ public class PeerProfile {
|
||||
|
||||
/** how large successfully sent messages are, calculated over a 1 minute, 1 hour, and 1 day period */
|
||||
public RateStat getSendSuccessSize() { return _sendSuccessSize; }
|
||||
/** how large messages that could not be sent were, calculated over a 1 minute, 1 hour, and 1 day period */
|
||||
public RateStat getSendFailureSize() { return _sendFailureSize; }
|
||||
/** how large received messages are, calculated over a 1 minute, 1 hour, and 1 day period */
|
||||
public RateStat getReceiveSize() { return _receiveSize; }
|
||||
/** how long it takes to get a db response from the peer (in milliseconds), calculated over a 1 minute, 1 hour, and 1 day period */
|
||||
@@ -164,10 +160,6 @@ public class PeerProfile {
|
||||
public RateStat getTunnelCreateResponseTime() { return _tunnelCreateResponseTime; }
|
||||
/** how long it takes to successfully test a tunnel this peer participates in (in milliseconds), calculated over a 10 minute, 1 hour, and 1 day period */
|
||||
public RateStat getTunnelTestResponseTime() { return _tunnelTestResponseTime; }
|
||||
/** how long it takes to successfully test the peer (in milliseconds) when the time exceeds 5s */
|
||||
public RateStat getTunnelTestResponseTimeSlow() { return _tunnelTestResponseTimeSlow; }
|
||||
/** how long between communication errors with the peer (disconnection, etc), calculated over a 1 minute, 1 hour, and 1 day period */
|
||||
public RateStat getCommError() { return _commError; }
|
||||
/** how many new peers we get from dbSearchReplyMessages or dbStore messages, calculated over a 1 hour, 1 day, and 1 week period */
|
||||
public RateStat getDbIntroduction() { return _dbIntroduction; }
|
||||
|
||||
@@ -179,14 +171,6 @@ public class PeerProfile {
|
||||
public long getSpeedBonus() { return _speedBonus; }
|
||||
public void setSpeedBonus(long bonus) { _speedBonus = bonus; }
|
||||
|
||||
/**
|
||||
* extra factor added to the reliability ranking - this can be updated in the profile
|
||||
* written to disk to affect how the algorithm ranks reliability. Negative values are
|
||||
* penalties
|
||||
*/
|
||||
public long getReliabilityBonus() { return _reliabilityBonus; }
|
||||
public void setReliabilityBonus(long bonus) { _reliabilityBonus = bonus; }
|
||||
|
||||
/**
|
||||
* extra factor added to the capacity ranking - this can be updated in the profile
|
||||
* written to disk to affect how the algorithm ranks capacity. Negative values are
|
||||
@@ -210,14 +194,6 @@ public class PeerProfile {
|
||||
*
|
||||
*/
|
||||
public double getSpeedValue() { return _speedValue; }
|
||||
public double getOldSpeedValue() { return _oldSpeedValue; }
|
||||
/**
|
||||
* How likely are they to stay up and pass on messages over the next few minutes.
|
||||
* Positive numbers means more likely, negative numbers means its probably not
|
||||
* even worth trying.
|
||||
*
|
||||
*/
|
||||
public double getReliabilityValue() { return _reliabilityValue; }
|
||||
/**
|
||||
* How many tunnels do we think this peer can handle over the next hour?
|
||||
*
|
||||
@@ -354,13 +330,10 @@ public class PeerProfile {
|
||||
*/
|
||||
public void shrinkProfile() {
|
||||
_sendSuccessSize = null;
|
||||
_sendFailureSize = null;
|
||||
_receiveSize = null;
|
||||
_dbResponseTime = null;
|
||||
_tunnelCreateResponseTime = null;
|
||||
_tunnelTestResponseTime = null;
|
||||
_tunnelTestResponseTimeSlow = null;
|
||||
_commError = null;
|
||||
_dbIntroduction = null;
|
||||
_tunnelHistory = null;
|
||||
_dbHistory = null;
|
||||
@@ -378,21 +351,15 @@ public class PeerProfile {
|
||||
public void expandProfile() {
|
||||
String group = (null == _peer ? "profileUnknown" : _peer.toBase64().substring(0,6));
|
||||
if (_sendSuccessSize == null)
|
||||
_sendSuccessSize = new RateStat("sendSuccessSize", "How large successfully sent messages are", group, new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
if (_sendFailureSize == null)
|
||||
_sendFailureSize = new RateStat("sendFailureSize", "How large messages that could not be sent were", group, new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000 } );
|
||||
_sendSuccessSize = new RateStat("sendSuccessSize", "How large successfully sent messages are", group, new long[] { 5*60*1000l, 60*60*1000l });
|
||||
if (_receiveSize == null)
|
||||
_receiveSize = new RateStat("receiveSize", "How large received messages are", group, new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000 } );
|
||||
_receiveSize = new RateStat("receiveSize", "How large received messages are", group, new long[] { 5*60*1000l, 60*60*1000l } );
|
||||
if (_dbResponseTime == null)
|
||||
_dbResponseTime = new RateStat("dbResponseTime", "how long it takes to get a db response from the peer (in milliseconds)", group, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000 } );
|
||||
if (_tunnelCreateResponseTime == null)
|
||||
_tunnelCreateResponseTime = new RateStat("tunnelCreateResponseTime", "how long it takes to get a tunnel create response from the peer (in milliseconds)", group, new long[] { 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000 } );
|
||||
if (_tunnelTestResponseTime == null)
|
||||
_tunnelTestResponseTime = new RateStat("tunnelTestResponseTime", "how long it takes to successfully test a tunnel this peer participates in (in milliseconds)", group, new long[] { 10*60*1000l, 30*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000 } );
|
||||
if (_tunnelTestResponseTimeSlow == null)
|
||||
_tunnelTestResponseTimeSlow = new RateStat("tunnelTestResponseTimeSlow", "how long it takes to successfully test a peer when the time exceeds 5s", group, new long[] { 10*60*1000l, 30*60*1000l, 60*60*1000l, 3*60*60*1000l, 24*60*60*1000l, });
|
||||
if (_commError == null)
|
||||
_commError = new RateStat("commErrorRate", "how long between communication errors with the peer (e.g. disconnection)", group, new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000 } );
|
||||
if (_dbIntroduction == null)
|
||||
_dbIntroduction = new RateStat("dbIntroduction", "how many new peers we get from dbSearchReplyMessages or dbStore messages", group, new long[] { 60*60*1000l, 6*60*60*1000l, 24*60*60*1000l });
|
||||
|
||||
@@ -402,18 +369,17 @@ public class PeerProfile {
|
||||
_dbHistory = new DBHistory(_context, group);
|
||||
|
||||
_sendSuccessSize.setStatLog(_context.statManager().getStatLog());
|
||||
_sendFailureSize.setStatLog(_context.statManager().getStatLog());
|
||||
_receiveSize.setStatLog(_context.statManager().getStatLog());
|
||||
_dbResponseTime.setStatLog(_context.statManager().getStatLog());
|
||||
_tunnelCreateResponseTime.setStatLog(_context.statManager().getStatLog());
|
||||
_tunnelTestResponseTime.setStatLog(_context.statManager().getStatLog());
|
||||
_tunnelTestResponseTimeSlow.setStatLog(_context.statManager().getStatLog());
|
||||
_commError.setStatLog(_context.statManager().getStatLog());
|
||||
_dbIntroduction.setStatLog(_context.statManager().getStatLog());
|
||||
_expanded = true;
|
||||
}
|
||||
/** once a day, on average, cut the measured throughtput values in half */
|
||||
private static final long DROP_PERIOD_MINUTES = 24*60;
|
||||
/** let's try once an hour times 3/4 */
|
||||
private static final int DROP_PERIOD_MINUTES = 60;
|
||||
private static final double DEGRADE_FACTOR = 0.75;
|
||||
private long _lastCoalesceDate = System.currentTimeMillis();
|
||||
private void coalesceThroughput() {
|
||||
long now = System.currentTimeMillis();
|
||||
@@ -430,46 +396,19 @@ public class PeerProfile {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (false && _log.shouldLog(Log.WARN) ) {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append("Updating throughput after ").append(tot).append(" to ");
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
buf.append(_peakThroughput[i]).append(',');
|
||||
buf.append(" for ").append(_peer.toBase64());
|
||||
_log.warn(buf.toString());
|
||||
}
|
||||
} else {
|
||||
if (_context.random().nextLong(DROP_PERIOD_MINUTES*2) <= 0) {
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
_peakThroughput[i] /= 2;
|
||||
|
||||
if (false && _log.shouldLog(Log.WARN) ) {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append("Degrading the throughput measurements to ");
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
buf.append(_peakThroughput[i]).append(',');
|
||||
buf.append(" for ").append(_peer.toBase64());
|
||||
_log.warn(buf.toString());
|
||||
}
|
||||
if (_context.random().nextInt(DROP_PERIOD_MINUTES*2) <= 0) {
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
_peakThroughput[i] *= DEGRADE_FACTOR;
|
||||
}
|
||||
}
|
||||
|
||||
// we degrade the tunnel throughput here too, regardless of the current
|
||||
// activity
|
||||
if (_context.random().nextLong(DROP_PERIOD_MINUTES*2) <= 0) {
|
||||
if (_context.random().nextInt(DROP_PERIOD_MINUTES*2) <= 0) {
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++) {
|
||||
_peakTunnelThroughput[i] /= 2;
|
||||
_peakTunnel1mThroughput[i] /= 2;
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.WARN) ) {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append("Degrading the tunnel throughput measurements to ");
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
buf.append(_peakTunnel1mThroughput[i]).append(',');
|
||||
buf.append(" for ").append(_peer.toBase64());
|
||||
_log.warn(buf.toString());
|
||||
_peakTunnelThroughput[i] *= DEGRADE_FACTOR;
|
||||
_peakTunnel1mThroughput[i] *= DEGRADE_FACTOR;
|
||||
}
|
||||
}
|
||||
_peakThroughputCurrentTotal = 0;
|
||||
@@ -480,34 +419,27 @@ public class PeerProfile {
|
||||
/** update the stats and rates (this should be called once a minute) */
|
||||
public void coalesceStats() {
|
||||
if (!_expanded) return;
|
||||
_commError.coalesceStats();
|
||||
_dbIntroduction.coalesceStats();
|
||||
_dbResponseTime.coalesceStats();
|
||||
_receiveSize.coalesceStats();
|
||||
_sendFailureSize.coalesceStats();
|
||||
_sendSuccessSize.coalesceStats();
|
||||
_tunnelCreateResponseTime.coalesceStats();
|
||||
_tunnelTestResponseTime.coalesceStats();
|
||||
_tunnelTestResponseTimeSlow.coalesceStats();
|
||||
_dbHistory.coalesceStats();
|
||||
_tunnelHistory.coalesceStats();
|
||||
|
||||
coalesceThroughput();
|
||||
|
||||
_speedValue = calculateSpeed();
|
||||
_oldSpeedValue = calculateOldSpeed();
|
||||
_reliabilityValue = calculateReliability();
|
||||
_capacityValue = calculateCapacity();
|
||||
_integrationValue = calculateIntegration();
|
||||
_isFailing = calculateIsFailing();
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Coalesced: speed [" + _speedValue + "] reliability [" + _reliabilityValue + "] capacity [" + _capacityValue + "] integration [" + _integrationValue + "] failing? [" + _isFailing + "]");
|
||||
_log.debug("Coalesced: speed [" + _speedValue + "] capacity [" + _capacityValue + "] integration [" + _integrationValue + "] failing? [" + _isFailing + "]");
|
||||
}
|
||||
|
||||
private double calculateSpeed() { return _context.speedCalculator().calc(this); }
|
||||
private double calculateOldSpeed() { return _context.oldSpeedCalculator().calc(this); }
|
||||
private double calculateReliability() { return _context.reliabilityCalculator().calc(this); }
|
||||
private double calculateCapacity() { return _context.capacityCalculator().calc(this); }
|
||||
private double calculateIntegration() { return _context.integrationCalculator().calc(this); }
|
||||
private boolean calculateIsFailing() { return _context.isFailingCalculator().calcBoolean(this); }
|
||||
@@ -584,7 +516,6 @@ public class PeerProfile {
|
||||
//profile.coalesceStats();
|
||||
buf.append("Peer " + profile.getPeer().toBase64()
|
||||
+ ":\t Speed:\t" + fmt.format(profile.calculateSpeed())
|
||||
+ " Reliability:\t" + fmt.format(profile.calculateReliability())
|
||||
+ " Capacity:\t" + fmt.format(profile.calculateCapacity())
|
||||
+ " Integration:\t" + fmt.format(profile.calculateIntegration())
|
||||
+ " Active?\t" + profile.getIsActive()
|
||||
|
@@ -50,7 +50,6 @@ public class ProfileManagerImpl implements ProfileManager {
|
||||
PeerProfile data = getProfile(peer);
|
||||
if (data == null) return;
|
||||
data.setLastSendFailed(_context.clock().now());
|
||||
data.getSendFailureSize().addData(0, 0); // yeah, should be a frequency...
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +60,6 @@ public class ProfileManagerImpl implements ProfileManager {
|
||||
PeerProfile data = getProfile(peer);
|
||||
if (data == null) return;
|
||||
data.setLastSendFailed(_context.clock().now());
|
||||
data.getSendFailureSize().addData(0, 0); // yeah, should be a frequency...
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,8 +72,6 @@ public class ProfileManagerImpl implements ProfileManager {
|
||||
PeerProfile data = getProfile(peer);
|
||||
if (data == null) return;
|
||||
data.setLastSendFailed(_context.clock().now());
|
||||
data.getSendFailureSize().addData(1, 0); // yeah, should be a frequency...
|
||||
data.getCommError().addData(1, 0); // see above
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,8 +121,6 @@ public class ProfileManagerImpl implements ProfileManager {
|
||||
if (data == null) return;
|
||||
data.updateTunnelTestTimeAverage(responseTimeMs);
|
||||
data.getTunnelTestResponseTime().addData(responseTimeMs, responseTimeMs);
|
||||
if (responseTimeMs > getSlowThreshold())
|
||||
data.getTunnelTestResponseTimeSlow().addData(responseTimeMs, responseTimeMs);
|
||||
}
|
||||
|
||||
public void tunnelDataPushed(Hash peer, long rtt, int size) {
|
||||
|
@@ -1028,7 +1028,7 @@ public class ProfileOrganizer {
|
||||
|
||||
/**
|
||||
* called after locking the reorganizeLock, place the profile in the appropriate tier.
|
||||
* This is where we implement the (betterThanAverage ? goToPierX : goToPierY) algorithms
|
||||
* This is where we implement the (betterThanAverage ? goToTierX : goToTierY) algorithms
|
||||
*
|
||||
*/
|
||||
private void locked_placeProfile(PeerProfile profile) {
|
||||
@@ -1153,7 +1153,6 @@ public class ProfileOrganizer {
|
||||
organizer.isHighCapacity(peer) ? "IR " :
|
||||
organizer.isFailing(peer) ? "IX " : "I ") + "]: "
|
||||
+ "\t Speed:\t" + fmt.format(profile.getSpeedValue())
|
||||
+ " Reliability:\t" + fmt.format(profile.getReliabilityValue())
|
||||
+ " Capacity:\t" + fmt.format(profile.getCapacityValue())
|
||||
+ " Integration:\t" + fmt.format(profile.getIntegrationValue())
|
||||
+ " Active?\t" + profile.getIsActive()
|
||||
@@ -1164,7 +1163,6 @@ public class ProfileOrganizer {
|
||||
organizer.isHighCapacity(peer) ? "R " :
|
||||
organizer.isFailing(peer) ? "X " : " ") + "]: "
|
||||
+ "\t Speed:\t" + fmt.format(profile.getSpeedValue())
|
||||
+ " Reliability:\t" + fmt.format(profile.getReliabilityValue())
|
||||
+ " Capacity:\t" + fmt.format(profile.getCapacityValue())
|
||||
+ " Integration:\t" + fmt.format(profile.getIntegrationValue())
|
||||
+ " Active?\t" + profile.getIsActive()
|
||||
|
@@ -95,7 +95,6 @@ class ProfilePersistenceHelper {
|
||||
if (_us != null)
|
||||
buf.append("# as calculated by ").append(_us.toBase64()).append(NL);
|
||||
buf.append("#").append(NL);
|
||||
buf.append("# reliability: ").append(profile.getReliabilityValue()).append(NL);
|
||||
buf.append("# capacity: ").append(profile.getCapacityValue()).append(NL);
|
||||
buf.append("# integration: ").append(profile.getIntegrationValue()).append(NL);
|
||||
buf.append("# speedValue: ").append(profile.getSpeedValue()).append(NL);
|
||||
@@ -134,15 +133,12 @@ class ProfilePersistenceHelper {
|
||||
|
||||
if (profile.getIsExpanded()) {
|
||||
// only write out expanded data if, uh, we've got it
|
||||
profile.getCommError().store(out, "commError");
|
||||
profile.getDbIntroduction().store(out, "dbIntroduction");
|
||||
profile.getDbResponseTime().store(out, "dbResponseTime");
|
||||
profile.getReceiveSize().store(out, "receiveSize");
|
||||
profile.getSendFailureSize().store(out, "sendFailureSize");
|
||||
profile.getSendSuccessSize().store(out, "sendSuccessSize");
|
||||
profile.getTunnelCreateResponseTime().store(out, "tunnelCreateResponseTime");
|
||||
profile.getTunnelTestResponseTime().store(out, "tunnelTestResponseTime");
|
||||
profile.getTunnelTestResponseTimeSlow().store(out, "tunnelTestResponseTimeSlow");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,15 +213,12 @@ class ProfilePersistenceHelper {
|
||||
profile.getTunnelHistory().load(props);
|
||||
profile.getDBHistory().load(props);
|
||||
|
||||
profile.getCommError().load(props, "commError", true);
|
||||
profile.getDbIntroduction().load(props, "dbIntroduction", true);
|
||||
profile.getDbResponseTime().load(props, "dbResponseTime", true);
|
||||
profile.getReceiveSize().load(props, "receiveSize", true);
|
||||
profile.getSendFailureSize().load(props, "sendFailureSize", true);
|
||||
profile.getSendSuccessSize().load(props, "sendSuccessSize", true);
|
||||
profile.getTunnelCreateResponseTime().load(props, "tunnelCreateResponseTime", true);
|
||||
profile.getTunnelTestResponseTime().load(props, "tunnelTestResponseTime", true);
|
||||
profile.getTunnelTestResponseTimeSlow().load(props, "tunnelTestResponseTimeSlow", true);
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Loaded the profile for " + peer.toBase64() + " from " + file.getName());
|
||||
|
@@ -1,91 +0,0 @@
|
||||
package net.i2p.router.peermanager;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.stat.RateStat;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Determine how reliable the peer is - how likely they'll be able to respond or
|
||||
* otherwise carry out whatever we ask them to (or even merely be reachable)
|
||||
*
|
||||
*/
|
||||
public class ReliabilityCalculator extends Calculator {
|
||||
private Log _log;
|
||||
private RouterContext _context;
|
||||
|
||||
public ReliabilityCalculator(RouterContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(ReliabilityCalculator.class);
|
||||
}
|
||||
|
||||
public double calc(PeerProfile profile) {
|
||||
// if we've never succeeded (even if we've never tried), the reliability is zip
|
||||
if (profile.getSendSuccessSize().getRate(60*60*1000).getLifetimeEventCount() < 0)
|
||||
return profile.getReliabilityBonus();
|
||||
|
||||
long val = 0;
|
||||
val += profile.getSendSuccessSize().getRate(60*1000).getCurrentEventCount() * 20;
|
||||
val += profile.getSendSuccessSize().getRate(60*1000).getLastEventCount() * 10;
|
||||
val += profile.getSendSuccessSize().getRate(60*60*1000).getLastEventCount() * 1;
|
||||
val += profile.getSendSuccessSize().getRate(60*60*1000).getCurrentEventCount() * 5;
|
||||
|
||||
val += profile.getTunnelCreateResponseTime().getRate(10*60*1000).getLastEventCount() * 5;
|
||||
val += profile.getTunnelCreateResponseTime().getRate(60*60*1000).getCurrentEventCount();
|
||||
val += profile.getTunnelCreateResponseTime().getRate(60*60*1000).getLastEventCount();
|
||||
|
||||
//val -= profile.getSendFailureSize().getRate(60*1000).getLastEventCount() * 5;
|
||||
//val -= profile.getSendFailureSize().getRate(60*60*1000).getCurrentEventCount()*2;
|
||||
//val -= profile.getSendFailureSize().getRate(60*60*1000).getLastEventCount()*2;
|
||||
|
||||
RateStat rejRate = profile.getTunnelHistory().getRejectionRate();
|
||||
if (rejRate.getRate(60*1000).getCurrentEventCount() > 0)
|
||||
val -= 200;
|
||||
if (rejRate.getRate(60*1000).getLastEventCount() > 0)
|
||||
val -= 100;
|
||||
if (rejRate.getRate(10*60*1000).getCurrentEventCount() > 0)
|
||||
val -= 10;
|
||||
if (rejRate.getRate(10*60*1000).getCurrentEventCount() > 0)
|
||||
val -= 5;
|
||||
|
||||
// penalize them heavily for dropping netDb requests (though these could have
|
||||
// failed due to tunnel timeouts, so don't be too mean)
|
||||
if (profile.getDBHistory().getFailedLookupRate().getRate(60*1000).getCurrentEventCount() > 0)
|
||||
val -= 10;
|
||||
if (profile.getDBHistory().getFailedLookupRate().getRate(60*1000).getLastEventCount() > 0)
|
||||
val -= 5;
|
||||
|
||||
// scream and shout on network errors
|
||||
if (profile.getCommError().getRate(60*1000).getCurrentEventCount() > 0)
|
||||
val -= 200;
|
||||
if (profile.getCommError().getRate(60*1000).getLastEventCount() > 0)
|
||||
val -= 200;
|
||||
|
||||
if (profile.getCommError().getRate(60*60*1000).getCurrentEventCount() > 0)
|
||||
val -= 10;
|
||||
if (profile.getCommError().getRate(60*60*1000).getLastEventCount() > 0)
|
||||
val -= 10;
|
||||
|
||||
val -= profile.getCommError().getRate(24*60*60*1000).getCurrentEventCount() * 1;
|
||||
|
||||
//long now = _context.clock().now();
|
||||
|
||||
long timeSinceRejection = 61*60*1000; // now - profile.getTunnelHistory().getLastRejected();
|
||||
if (timeSinceRejection > 60*60*1000) {
|
||||
// noop. rejection was over 60 minutes ago
|
||||
} else if (timeSinceRejection > 10*60*1000) {
|
||||
val -= 10; // 10-60 minutes ago we got a rejection
|
||||
} else if (timeSinceRejection > 60*1000) {
|
||||
val -= 50; // 1-10 minutes ago we got a rejection
|
||||
} else {
|
||||
val -= 100; // we got a rejection within the last minute
|
||||
}
|
||||
|
||||
//if ( (profile.getLastSendSuccessful() > 0) && (now - 24*60*60*1000 > profile.getLastSendSuccessful()) ) {
|
||||
// // we know they're real, but we havent sent them a message successfully in over a day.
|
||||
// val -= 1000;
|
||||
//}
|
||||
|
||||
val += profile.getReliabilityBonus();
|
||||
return val;
|
||||
}
|
||||
}
|
@@ -1,90 +0,0 @@
|
||||
package net.i2p.router.peermanager;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.stat.Rate;
|
||||
import net.i2p.stat.RateStat;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Simple speed calculator that just counts how many messages go through the
|
||||
* tunnel.
|
||||
*
|
||||
*/
|
||||
public class StrictSpeedCalculator extends Calculator {
|
||||
private Log _log;
|
||||
private RouterContext _context;
|
||||
|
||||
public StrictSpeedCalculator(RouterContext context) {
|
||||
_context = context;
|
||||
_log = context.logManager().getLog(StrictSpeedCalculator.class);
|
||||
}
|
||||
|
||||
public double calc(PeerProfile profile) {
|
||||
return countSuccesses(profile);
|
||||
}
|
||||
private double countSuccesses(PeerProfile profile) {
|
||||
RateStat success = profile.getTunnelHistory().getProcessSuccessRate();
|
||||
RateStat failure = profile.getTunnelHistory().getProcessFailureRate();
|
||||
return messagesPerMinute(success, failure);
|
||||
}
|
||||
private double messagesPerMinute(RateStat success, RateStat failure) {
|
||||
double rv = 0.0d;
|
||||
if (success != null) {
|
||||
Rate rate = null;
|
||||
long periods[] = success.getPeriods();
|
||||
for (int i = 0; i < periods.length; i++) {
|
||||
rate = success.getRate(periods[i]);
|
||||
if ( (rate != null) && (rate.getCurrentTotalValue() > 0) )
|
||||
break;
|
||||
}
|
||||
|
||||
double value = rate.getCurrentTotalValue();
|
||||
value += rate.getLastTotalValue();
|
||||
rv = value * 10.0d * 60.0d * 1000.0d / (double)rate.getPeriod();
|
||||
|
||||
// if any of the messages are getting fragmented and cannot be
|
||||
// handled, penalize like crazy
|
||||
Rate fail = failure.getRate(rate.getPeriod());
|
||||
if (fail.getCurrentTotalValue() > 0)
|
||||
rv /= fail.getCurrentTotalValue();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
public double calc(PeerProfile profile) {
|
||||
double successCount = countSuccesses(profile);
|
||||
double failureCount = countFailures(profile);
|
||||
|
||||
double rv = successCount - 5*failureCount;
|
||||
if (rv < 0)
|
||||
rv = 0;
|
||||
return rv;
|
||||
}
|
||||
private double countSuccesses(PeerProfile profile) {
|
||||
RateStat success = profile.getTunnelHistory().getProcessSuccessRate();
|
||||
return messagesPerMinute(success);
|
||||
}
|
||||
private double countFailures(PeerProfile profile) {
|
||||
RateStat failure = profile.getTunnelHistory().getProcessFailureRate();
|
||||
return messagesPerMinute(failure);
|
||||
}
|
||||
private double messagesPerMinute(RateStat stat) {
|
||||
double rv = 0.0d;
|
||||
if (stat != null) {
|
||||
Rate rate = null;
|
||||
long periods[] = stat.getPeriods();
|
||||
for (int i = 0; i < periods.length; i++) {
|
||||
rate = stat.getRate(periods[i]);
|
||||
if ( (rate != null) && (rate.getCurrentTotalValue() > 0) )
|
||||
break;
|
||||
}
|
||||
|
||||
double value = rate.getCurrentTotalValue();
|
||||
value += rate.getLastTotalValue();
|
||||
rv = value * 60.0d * 1000.0d / (double)rate.getPeriod();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
*/
|
||||
}
|
@@ -26,8 +26,6 @@ public class TunnelHistory {
|
||||
private volatile long _lastFailed;
|
||||
private RateStat _rejectRate;
|
||||
private RateStat _failRate;
|
||||
private RateStat _processSuccessRate;
|
||||
private RateStat _processFailureRate;
|
||||
private String _statGroup;
|
||||
|
||||
/** probabalistic tunnel rejection due to a flood of requests */
|
||||
@@ -47,14 +45,10 @@ public class TunnelHistory {
|
||||
}
|
||||
|
||||
private void createRates(String statGroup) {
|
||||
_rejectRate = new RateStat("tunnelHistory.rejectRate", "How often does this peer reject a tunnel request?", statGroup, new long[] { 60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_failRate = new RateStat("tunnelHistory.failRate", "How often do tunnels this peer accepts fail?", statGroup, new long[] { 60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_processSuccessRate = new RateStat("tunnelHistory.processSuccessRate", "How many messages does a tunnel process?", statGroup, new long[] { 5*60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_processFailureRate = new RateStat("tunnelHistory.processfailureRate", "How many messages does a tunnel fail?", statGroup, new long[] { 5*60*1000l, 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_rejectRate = new RateStat("tunnelHistory.rejectRate", "How often does this peer reject a tunnel request?", statGroup, new long[] { 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_failRate = new RateStat("tunnelHistory.failRate", "How often do tunnels this peer accepts fail?", statGroup, new long[] { 10*60*1000l, 30*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||
_rejectRate.setStatLog(_context.statManager().getStatLog());
|
||||
_failRate.setStatLog(_context.statManager().getStatLog());
|
||||
_processSuccessRate.setStatLog(_context.statManager().getStatLog());
|
||||
_processFailureRate.setStatLog(_context.statManager().getStatLog());
|
||||
}
|
||||
|
||||
/** total tunnels the peer has agreed to participate in */
|
||||
@@ -77,10 +71,7 @@ public class TunnelHistory {
|
||||
public long getLastFailed() { return _lastFailed; }
|
||||
|
||||
public void incrementProcessed(int processedSuccessfully, int failedProcessing) {
|
||||
if (processedSuccessfully > 0)
|
||||
_processSuccessRate.addData(processedSuccessfully, 0);
|
||||
if (failedProcessing > 0)
|
||||
_processFailureRate.addData(failedProcessing, 0);
|
||||
// old strict speed calculator
|
||||
}
|
||||
|
||||
public void incrementAgreedTo() {
|
||||
@@ -129,16 +120,12 @@ public class TunnelHistory {
|
||||
|
||||
public RateStat getRejectionRate() { return _rejectRate; }
|
||||
public RateStat getFailedRate() { return _failRate; }
|
||||
public RateStat getProcessSuccessRate() { return _processSuccessRate; }
|
||||
public RateStat getProcessFailureRate() { return _processFailureRate; }
|
||||
|
||||
public void coalesceStats() {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Coallescing stats");
|
||||
_rejectRate.coalesceStats();
|
||||
_failRate.coalesceStats();
|
||||
_processFailureRate.coalesceStats();
|
||||
_processSuccessRate.coalesceStats();
|
||||
}
|
||||
|
||||
private final static String NL = System.getProperty("line.separator");
|
||||
@@ -161,8 +148,6 @@ public class TunnelHistory {
|
||||
out.write(buf.toString().getBytes());
|
||||
_rejectRate.store(out, "tunnelHistory.rejectRate");
|
||||
_failRate.store(out, "tunnelHistory.failRate");
|
||||
_processSuccessRate.store(out, "tunnelHistory.processSuccessRate");
|
||||
_processFailureRate.store(out, "tunnelHistory.processFailureRate");
|
||||
}
|
||||
|
||||
private void add(StringBuffer buf, String name, long val, String description) {
|
||||
@@ -187,12 +172,6 @@ public class TunnelHistory {
|
||||
_failRate.load(props, "tunnelHistory.failRate", true);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Loading tunnelHistory.failRate");
|
||||
_processFailureRate.load(props, "tunnelHistory.processFailureRate", true);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Loading tunnelHistory.processFailureRate");
|
||||
_processSuccessRate.load(props, "tunnelHistory.processSuccessRate", true);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Loading tunnelHistory.processSuccessRate");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
_log.warn("TunnelHistory rates are corrupt, resetting", iae);
|
||||
createRates(_statGroup);
|
||||
|
Reference in New Issue
Block a user