Search in sources :

Example 11 with RateStat

use of net.i2p.stat.RateStat in project i2p.i2p by i2p.

the class RouterWatchdog method monitorRouter.

public void monitorRouter() {
    boolean ok = verifyJobQueueLiveliness();
    // If we aren't connected to the network that's why there's nobody to talk to
    long netErrors = 0;
    if (_context.commSystem().getStatus() == Status.DISCONNECTED) {
        netErrors = 10;
    } else {
        RateStat rs = _context.statManager().getRate("udp.sendException");
        if (rs != null) {
            Rate r = rs.getRate(60 * 1000);
            if (r != null)
                netErrors = r.getLastEventCount();
        }
    }
    ok = ok && (verifyClientLiveliness() || netErrors >= 5);
    if (ok) {
        _consecutiveErrors = 0;
    } else {
        _consecutiveErrors++;
        dumpStatus();
        if (shutdownOnHang()) {
            _log.log(Log.CRIT, "Router hung!  Restart forced by watchdog!");
            try {
                Thread.sleep(30 * 1000);
            } catch (InterruptedException ie) {
            }
            // halt and not system.exit, since some of the shutdown hooks might be misbehaving
            Runtime.getRuntime().halt(Router.EXIT_HARD_RESTART);
        }
    }
}
Also used : RateStat(net.i2p.stat.RateStat) Rate(net.i2p.stat.Rate)

Example 12 with RateStat

use of net.i2p.stat.RateStat in project i2p.i2p by i2p.

the class StatSummarizer method parseSpecs.

/**
 * @param specs statName.period,statName.period,statName.period
 * @return list of Rate objects
 * @since public since 0.9.33, was package private
 */
public Set<Rate> parseSpecs(String specs) {
    if (specs == null)
        return Collections.emptySet();
    StringTokenizer tok = new StringTokenizer(specs, ",");
    Set<Rate> rv = new HashSet<Rate>();
    while (tok.hasMoreTokens()) {
        String spec = tok.nextToken();
        int split = spec.lastIndexOf('.');
        if ((split <= 0) || (split + 1 >= spec.length()))
            continue;
        String name = spec.substring(0, split);
        String per = spec.substring(split + 1);
        long period = -1;
        try {
            period = Long.parseLong(per);
            RateStat rs = _context.statManager().getRate(name);
            if (rs != null) {
                Rate r = rs.getRate(period);
                if (r != null)
                    rv.add(r);
            }
        } catch (NumberFormatException nfe) {
        }
    }
    return rv;
}
Also used : RateStat(net.i2p.stat.RateStat) StringTokenizer(java.util.StringTokenizer) Rate(net.i2p.stat.Rate) HashSet(java.util.HashSet)

Example 13 with RateStat

use of net.i2p.stat.RateStat in project i2p.i2p by i2p.

the class TunnelPool method setLengthOverride.

/**
 *  Shorten the length when under extreme stress, else clear the override.
 *  We only do this for exploratory tunnels, since we have to build a fallback
 *  if we run out. It's much better to have a shorter tunnel than a fallback.
 *
 *  @since 0.8.11
 */
private void setLengthOverride() {
    if (!_settings.isExploratory())
        return;
    int len = _settings.getLength();
    if (len > 1) {
        RateStat e = _context.statManager().getRate("tunnel.buildExploratoryExpire");
        RateStat r = _context.statManager().getRate("tunnel.buildExploratoryReject");
        RateStat s = _context.statManager().getRate("tunnel.buildExploratorySuccess");
        if (e != null && r != null && s != null) {
            Rate er = e.getRate(10 * 60 * 1000);
            Rate rr = r.getRate(10 * 60 * 1000);
            Rate sr = s.getRate(10 * 60 * 1000);
            if (er != null && rr != null && sr != null) {
                RateAverages ra = RateAverages.getTemp();
                long ec = er.computeAverages(ra, false).getTotalEventCount();
                long rc = rr.computeAverages(ra, false).getTotalEventCount();
                long sc = sr.computeAverages(ra, false).getTotalEventCount();
                long tot = ec + rc + sc;
                if (tot >= BUILD_TRIES_LENGTH_OVERRIDE_1) {
                    long succ = 1000 * sc / tot;
                    if (succ <= 1000 / BUILD_TRIES_LENGTH_OVERRIDE_1) {
                        if (len > 2 && succ <= 1000 / BUILD_TRIES_LENGTH_OVERRIDE_2)
                            _settings.setLengthOverride(len - 2);
                        else
                            _settings.setLengthOverride(len - 1);
                        return;
                    }
                }
            }
        }
    }
    // disable
    _settings.setLengthOverride(-1);
}
Also used : RateStat(net.i2p.stat.RateStat) Rate(net.i2p.stat.Rate) RateAverages(net.i2p.stat.RateAverages)

Example 14 with RateStat

use of net.i2p.stat.RateStat in project i2p.i2p by i2p.

the class TunnelPool method getAdjustedTotalQuantity.

/**
 *  Return settings.getTotalQuantity, unless this is an exploratory tunnel
 *  AND exploratory build success rate is less than 1/10, AND total settings
 *  is greater than 1. Otherwise subtract 1 to help prevent congestion collapse,
 *  and prevent really unintegrated routers from working too hard.
 *  We only do this for exploratory as different clients could have different
 *  length settings. Although I guess inbound and outbound exploratory
 *  could be different too, and inbound is harder...
 *
 *  As of 0.9.19, add more if exploratory and floodfill, as floodfills
 *  generate a lot of exploratory traffic.
 *  TODO high-bandwidth non-floodfills do also...
 *
 *  @since 0.8.11
 */
private int getAdjustedTotalQuantity() {
    int rv = _settings.getTotalQuantity();
    // TODO high-bw non-ff also
    if (_settings.isExploratory() && _context.netDb().floodfillEnabled() && _context.router().getUptime() > 5 * 60 * 1000) {
        rv += 2;
    }
    if (_settings.isExploratory() && rv > 1) {
        RateStat e = _context.statManager().getRate("tunnel.buildExploratoryExpire");
        RateStat r = _context.statManager().getRate("tunnel.buildExploratoryReject");
        RateStat s = _context.statManager().getRate("tunnel.buildExploratorySuccess");
        if (e != null && r != null && s != null) {
            Rate er = e.getRate(10 * 60 * 1000);
            Rate rr = r.getRate(10 * 60 * 1000);
            Rate sr = s.getRate(10 * 60 * 1000);
            if (er != null && rr != null && sr != null) {
                RateAverages ra = RateAverages.getTemp();
                long ec = er.computeAverages(ra, false).getTotalEventCount();
                long rc = rr.computeAverages(ra, false).getTotalEventCount();
                long sc = sr.computeAverages(ra, false).getTotalEventCount();
                long tot = ec + rc + sc;
                if (tot >= BUILD_TRIES_QUANTITY_OVERRIDE) {
                    if (1000 * sc / tot <= 1000 / BUILD_TRIES_QUANTITY_OVERRIDE)
                        rv--;
                }
            }
        }
    }
    if (_settings.isExploratory() && _context.router().getUptime() < STARTUP_TIME) {
        // more exploratory during startup, when we are refreshing the netdb RIs
        rv++;
    }
    return rv;
}
Also used : RateStat(net.i2p.stat.RateStat) Rate(net.i2p.stat.Rate) RateAverages(net.i2p.stat.RateAverages)

Example 15 with RateStat

use of net.i2p.stat.RateStat in project i2p.i2p by i2p.

the class TunnelPool method countHowManyToBuild.

/**
 * Gather the data to see how many tunnels to build, and then actually compute that value (delegated to
 * the countHowManyToBuild function below)
 */
int countHowManyToBuild() {
    if (!isAlive()) {
        return 0;
    }
    int wanted = getAdjustedTotalQuantity();
    boolean allowZeroHop = ((getSettings().getLength() + getSettings().getLengthVariance()) <= 0);
    /**
     * This algorithm builds based on the previous average length of time it takes
     * to build a tunnel. This average is kept in the _buildRateName stat.
     * It is a separate stat for each type of pool, since in and out building use different methods,
     * as do exploratory and client pools,
     * and each pool can have separate length and length variance settings.
     * We add one minute to the stat for safety (two for exploratory tunnels).
     *
     * We linearly increase the number of builds per expiring tunnel from
     * 1 to PANIC_FACTOR as the time-to-expire gets shorter.
     *
     * The stat will be 0 for first 10m of uptime so we will use the older, conservative algorithm
     * below instead. This algorithm will take about 30m of uptime to settle down.
     * Or, if we are building more than 33% of the time something is seriously wrong,
     * we also use the conservative algorithm instead
     */
    final String rateName = buildRateName();
    // Compute the average time it takes us to build a single tunnel of this type.
    int avg = 0;
    RateStat rs = _context.statManager().getRate(rateName);
    if (rs == null) {
        // Create the RateStat here rather than at the top because
        // the user could change the length settings while running
        _context.statManager().createRequiredRateStat(rateName, "Tunnel Build Frequency", "Tunnels", new long[] { TUNNEL_LIFETIME });
        rs = _context.statManager().getRate(rateName);
    }
    if (rs != null) {
        Rate r = rs.getRate(TUNNEL_LIFETIME);
        if (r != null)
            avg = (int) (TUNNEL_LIFETIME * r.getAverageValue() / wanted);
    }
    if (avg > 0 && avg < TUNNEL_LIFETIME / 3) {
        // if we're taking less than 200s per tunnel to build
        // how many builds to kick off when time gets short
        final int PANIC_FACTOR = 4;
        // one minute safety factor
        avg += 60 * 1000;
        if (_settings.isExploratory())
            // two minute safety factor
            avg += 60 * 1000;
        long now = _context.clock().now();
        int expireSoon = 0;
        int expireLater = 0;
        int[] expireTime;
        int fallback = 0;
        synchronized (_tunnels) {
            expireTime = new int[_tunnels.size()];
            for (int i = 0; i < _tunnels.size(); i++) {
                TunnelInfo info = _tunnels.get(i);
                if (allowZeroHop || (info.getLength() > 1)) {
                    int timeToExpire = (int) (info.getExpiration() - now);
                    if (timeToExpire > 0 && timeToExpire < avg) {
                        expireTime[expireSoon++] = timeToExpire;
                    } else {
                        expireLater++;
                    }
                } else if (info.getExpiration() - now > avg) {
                    fallback++;
                }
            }
        }
        int inProgress;
        synchronized (_inProgress) {
            inProgress = _inProgress.size();
        }
        int remainingWanted = (wanted - expireLater) - inProgress;
        if (allowZeroHop)
            remainingWanted -= fallback;
        int rv = 0;
        int latesttime = 0;
        if (remainingWanted > 0) {
            if (remainingWanted > expireSoon) {
                // for tunnels completely missing
                rv = PANIC_FACTOR * (remainingWanted - expireSoon);
                remainingWanted = expireSoon;
            }
            // the other ones are extras
            for (int i = 0; i < remainingWanted; i++) {
                int latestidx = 0;
                // given the small size of the array this is efficient enough
                for (int j = 0; j < expireSoon; j++) {
                    if (expireTime[j] > latesttime) {
                        latesttime = expireTime[j];
                        latestidx = j;
                    }
                }
                expireTime[latestidx] = 0;
                if (latesttime > avg / 2)
                    rv += 1;
                else
                    rv += 2 + ((PANIC_FACTOR - 2) * (((avg / 2) - latesttime) / (avg / 2)));
            }
        }
        if (rv > 0 && _log.shouldLog(Log.DEBUG))
            _log.debug("New Count: rv: " + rv + " allow? " + allowZeroHop + " avg " + avg + " latesttime " + latesttime + " soon " + expireSoon + " later " + expireLater + " std " + wanted + " inProgress " + inProgress + " fallback " + fallback + " for " + toString());
        _context.statManager().addRateData(rateName, rv + inProgress, 0);
        return rv;
    }
    // fixed, conservative algorithm - starts building 3 1/2 - 6m before expiration
    // (210 or 270s) + (0..90s random)
    // + _settings.getRebuildPeriod() + _expireSkew;
    long expireAfter = _context.clock().now() + _expireSkew;
    int expire30s = 0;
    int expire90s = 0;
    int expire150s = 0;
    int expire210s = 0;
    int expire270s = 0;
    int expireLater = 0;
    int fallback = 0;
    synchronized (_tunnels) {
        for (int i = 0; i < _tunnels.size(); i++) {
            TunnelInfo info = _tunnels.get(i);
            if (allowZeroHop || (info.getLength() > 1)) {
                long timeToExpire = info.getExpiration() - expireAfter;
                if (timeToExpire <= 0) {
                // consider it unusable
                } else if (timeToExpire <= 30 * 1000) {
                    expire30s++;
                } else if (timeToExpire <= 90 * 1000) {
                    expire90s++;
                } else if (timeToExpire <= 150 * 1000) {
                    expire150s++;
                } else if (timeToExpire <= 210 * 1000) {
                    expire210s++;
                } else if (timeToExpire <= 270 * 1000) {
                    expire270s++;
                } else {
                    expireLater++;
                }
            } else if (info.getExpiration() > expireAfter) {
                fallback++;
            }
        }
    }
    int inProgress = 0;
    synchronized (_inProgress) {
        inProgress = _inProgress.size();
        for (int i = 0; i < inProgress; i++) {
            PooledTunnelCreatorConfig cfg = _inProgress.get(i);
            if (cfg.getLength() <= 1)
                fallback++;
        }
    }
    int rv = countHowManyToBuild(allowZeroHop, expire30s, expire90s, expire150s, expire210s, expire270s, expireLater, wanted, inProgress, fallback);
    _context.statManager().addRateData(rateName, (rv > 0 || inProgress > 0) ? 1 : 0, 0);
    return rv;
}
Also used : RateStat(net.i2p.stat.RateStat) Rate(net.i2p.stat.Rate) TunnelInfo(net.i2p.router.TunnelInfo)

Aggregations

RateStat (net.i2p.stat.RateStat)33 Rate (net.i2p.stat.Rate)24 Hash (net.i2p.data.Hash)5 RouterInfo (net.i2p.data.router.RouterInfo)5 RateAverages (net.i2p.stat.RateAverages)4 PeerProfile (net.i2p.router.peermanager.PeerProfile)3 ArrayList (java.util.ArrayList)2 RouterContext (net.i2p.router.RouterContext)2 StatManager (net.i2p.stat.StatManager)2 File (java.io.File)1 IOException (java.io.IOException)1 HashSet (java.util.HashSet)1 StringTokenizer (java.util.StringTokenizer)1 TreeSet (java.util.TreeSet)1 RouterAddress (net.i2p.data.router.RouterAddress)1 CommSystemFacade (net.i2p.router.CommSystemFacade)1 TunnelInfo (net.i2p.router.TunnelInfo)1 DBHistory (net.i2p.router.peermanager.DBHistory)1 HopConfig (net.i2p.router.tunnel.HopConfig)1 TunnelPool (net.i2p.router.tunnel.pool.TunnelPool)1