Search in sources :

Example 1 with CommSystemFacade

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;
}
Also used : CommSystemFacade(net.i2p.router.CommSystemFacade) Rate(net.i2p.stat.Rate) RouterInfo(net.i2p.data.router.RouterInfo) ArrayList(java.util.ArrayList) Hash(net.i2p.data.Hash) RateStat(net.i2p.stat.RateStat)

Aggregations

ArrayList (java.util.ArrayList)1 Hash (net.i2p.data.Hash)1 RouterInfo (net.i2p.data.router.RouterInfo)1 CommSystemFacade (net.i2p.router.CommSystemFacade)1 Rate (net.i2p.stat.Rate)1 RateStat (net.i2p.stat.RateStat)1