use of net.i2p.router.CommSystemFacade in project i2p.i2p by i2p.
the class BuildExecutor method allowed.
private int allowed() {
CommSystemFacade csf = _context.commSystem();
if (csf.getStatus() == Status.DISCONNECTED)
return 0;
if (csf.isDummy() && csf.getEstablished().size() <= 0)
return 0;
int maxKBps = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
// Max. 1 concurrent build per 6 KB/s outbound
int allowed = maxKBps / 6;
RateStat rs = _context.statManager().getRate("tunnel.buildRequestTime");
if (rs != null) {
Rate r = rs.getRate(60 * 1000);
double avg = 0;
if (r != null)
avg = r.getAverageValue();
if (avg <= 0)
avg = rs.getLifetimeAverageValue();
if (avg > 1) {
// If builds take more than 75 ms, start throttling
int throttle = (int) (75 * MAX_CONCURRENT_BUILDS / avg);
if (throttle < allowed) {
allowed = throttle;
if (allowed < MAX_CONCURRENT_BUILDS && _log.shouldLog(Log.INFO))
_log.info("Throttling max builds to " + allowed + " due to avg build time of " + ((int) avg) + " ms");
}
}
}
if (allowed < 2)
// Never choke below 2 builds (but congestion may)
allowed = 2;
else if (allowed > MAX_CONCURRENT_BUILDS)
allowed = MAX_CONCURRENT_BUILDS;
allowed = _context.getProperty("router.tunnelConcurrentBuilds", allowed);
// expire any REALLY old requests
long expireBefore = _context.clock().now() + 10 * 60 * 1000 - BuildRequestor.REQUEST_TIMEOUT - GRACE_PERIOD;
for (Iterator<PooledTunnelCreatorConfig> iter = _recentlyBuildingMap.values().iterator(); iter.hasNext(); ) {
PooledTunnelCreatorConfig cfg = iter.next();
if (cfg.getExpiration() <= expireBefore) {
iter.remove();
}
}
// expire any old requests
List<PooledTunnelCreatorConfig> expired = null;
int concurrent = 0;
// Todo: Make expiration variable
expireBefore = _context.clock().now() + 10 * 60 * 1000 - BuildRequestor.REQUEST_TIMEOUT;
for (Iterator<PooledTunnelCreatorConfig> iter = _currentlyBuildingMap.values().iterator(); iter.hasNext(); ) {
PooledTunnelCreatorConfig cfg = iter.next();
if (cfg.getExpiration() <= expireBefore) {
// save them for another minute
_recentlyBuildingMap.putIfAbsent(Long.valueOf(cfg.getReplyMessageId()), cfg);
iter.remove();
if (expired == null)
expired = new ArrayList<PooledTunnelCreatorConfig>();
expired.add(cfg);
}
}
concurrent = _currentlyBuildingMap.size();
allowed -= concurrent;
if (expired != null) {
for (int i = 0; i < expired.size(); i++) {
PooledTunnelCreatorConfig cfg = expired.get(i);
if (_log.shouldLog(Log.INFO))
_log.info("Timed out waiting for reply asking for " + cfg);
// Also note the fact that this tunnel request timed out in the peers' profiles.
for (int iPeer = 0; iPeer < cfg.getLength(); iPeer++) {
// Look up peer
Hash peer = cfg.getPeer(iPeer);
// Avoid recording ourselves
if (peer.equals(_context.routerHash()))
continue;
// Look up routerInfo
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(peer);
// Default and detect bandwidth tier
String bwTier = "Unknown";
// Returns "Unknown" if none recognized
if (ri != null)
bwTier = ri.getBandwidthTier();
// Record that a peer of the given tier expired
_context.statManager().addRateData("tunnel.tierExpire" + bwTier, 1);
didNotReply(cfg.getReplyMessageId(), peer);
// Blame everybody since we don't know whose fault it is.
// (it could be our exploratory tunnel's fault too...)
_context.profileManager().tunnelTimedOut(peer);
}
TunnelPool pool = cfg.getTunnelPool();
if (pool != null)
pool.buildComplete(cfg);
if (cfg.getDestination() == null) {
_context.statManager().addRateData("tunnel.buildExploratoryExpire", 1);
// if (cfg.isInbound())
// _context.statManager().addRateData("tunnel.buildExploratoryExpireIB", 1);
// else
// _context.statManager().addRateData("tunnel.buildExploratoryExpireOB", 1);
} else {
_context.statManager().addRateData("tunnel.buildClientExpire", 1);
// if (cfg.isInbound())
// _context.statManager().addRateData("tunnel.buildClientExpireIB", 1);
// else
// _context.statManager().addRateData("tunnel.buildClientExpireOB", 1);
}
}
}
_context.statManager().addRateData("tunnel.concurrentBuilds", concurrent, 0);
long lag = _context.jobQueue().getMaxLag();
if ((lag > 2000) && (_context.router().getUptime() > 5 * 60 * 1000)) {
if (_log.shouldLog(Log.WARN))
_log.warn("Too lagged [" + lag + "], don't allow building");
_context.statManager().addRateData("tunnel.concurrentBuildsLagged", concurrent, lag);
// if we have a job heavily blocking our jobqueue, ssllloowww dddooowwwnnn
return 0;
}
return allowed;
}
Aggregations