Changeset ab4f3008


Ignore:
Timestamp:
Dec 9, 2005 8:05:44 AM (15 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
e5fa7e0
Parents:
f738a02
git-author:
jrandom <jrandom> (12/09/05 08:05:44)
git-committer:
zzz <zzz@…> (12/09/05 08:05:44)
Message:

2005-12-09 zzz

  • Create different strategies for exploratory tunnels (which are difficult to create) and client tunnels (which are much easier)
  • Gradually increase number of parallel build attempts as tunnel expiry nears.
  • Temporarily shorten attempted build tunnel length if builds using configured tunnel length are unsuccessful
  • React more aggressively to tunnel failure than routine tunnel replacement
  • Make tunnel creation times randomized - there is existing code to randomize the tunnels but it isn't effective due to the tunnel creation strategy. Currently, most tunnels get built all at once, at about 2 ½ to 3 minutes before expiration. The patch fixes this by fixing the randomization, and by changing the overlap time (with old tunnels) to a range of 2 to 4 minutes.
  • Reduce number of excess tunnels. Lots of excess tunnels get created due to overlapping calls. Just about anything generated a call which could build many tunnels all at once, even if tunnel building was already in process.
  • Miscellaneous router console enhancements
Files:
2 added
18 edited

Legend:

Unmodified
Added
Removed
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java

    rf738a02 rab4f3008  
    6060        }
    6161        buf.append("</textarea><br />\n");
     62        buf.append("<i>Add additional logging statements above. Example: net.i2p.router.tunnel=WARN</i><br>");
     63        buf.append("<i>Or put entries in the logger.config file. Example: logger.record.net.i2p.router.tunnel=WARN</i><br>");
    6264        buf.append("<i>Valid levels are DEBUG, INFO, WARN, ERROR, CRIT</i>\n");
    6365        return buf.toString();
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHandler.java

    rf738a02 rab4f3008  
    136136            boolean saved = _context.router().saveConfig();
    137137            if (saved)
    138                 addFormNotice("Configuration saved successfully");
     138                addFormNotice("Exploratory tunnel configuration saved successfully");
    139139            else
    140140                addFormNotice("Error saving the configuration (applied but not saved) - please see the error logs");
  • apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java

    rf738a02 rab4f3008  
    8484        long ms = _context.clock().getOffset();
    8585       
    86         if (ms < 60 * 1000) {
    87             return now + " (" + (ms / 1000) + "s)";
    88         } else if (ms < 60 * 60 * 1000) {
    89             return now + " (" + (ms / (60 * 1000)) + "m)";
    90         } else if (ms < 24 * 60 * 60 * 1000) {
    91             return now + " (" + (ms / (60 * 60 * 1000)) + "h)";
     86        long diff = ms;
     87        if (diff < 0)
     88            diff = 0 - diff;
     89        if (diff == 0) {
     90            return now + " (no skew)";
     91        } else if (diff < 1000) {
     92            return now + " (" + ms + "ms skew)";
     93        } else if (diff < 5 * 1000) {
     94            return now + " (" + (ms / 1000) + "s skew)";
     95        } else if (diff < 60 * 1000) {
     96            return now + " <b>(" + (ms / 1000) + "s skew)</b>";
     97        } else if (diff < 60 * 60 * 1000) {
     98            return now + " <b>(" + (ms / (60 * 1000)) + "m skew)</b>";
     99        } else if (diff < 24 * 60 * 60 * 1000) {
     100            return now + " <b>(" + (ms / (60 * 60 * 1000)) + "h skew)</b>";
    92101        } else {
    93             return now + " (" + (ms / (24 * 60 * 60 * 1000)) + "d)";
     102            return now + " <b>(" + (ms / (24 * 60 * 60 * 1000)) + "d skew)</b>";
    94103        }
    95104    }
     
    410419   
    411420    /**
     421     * How many inbound client tunnels we have.
     422     *
     423     */
     424    public int getInboundClientTunnels() {
     425        if (_context == null)
     426            return 0;
     427        else
     428            return _context.tunnelManager().getInboundClientTunnelCount();
     429    }
     430   
     431    /**
     432     * How many active outbound client tunnels we have.
     433     *
     434     */
     435    public int getOutboundClientTunnels() {
     436        if (_context == null)
     437            return 0;
     438        else
     439            return _context.tunnelManager().getOutboundClientTunnelCount();
     440    }
     441   
     442    /**
    412443     * How many tunnels we are participating in.
    413444     *
  • apps/routerconsole/jsp/configtunnels.jsp

    rf738a02 rab4f3008  
    3434 <jsp:getProperty name="tunnelshelper" property="form" />
    3535 <hr />
     36 <i>Note - Exploratory tunnel setting changes are stored in the router.config file.</i></br>
     37 <i>Client tunnel changes are temporary and are not saved.</i><br>
     38 <i>To make permanent client tunnel changes see the </i><a href="i2ptunnel/index.jsp">i2ptunnel page</a>.<br>
    3639 <input type="submit" name="shouldsave" value="Save changes" /> <input type="reset" value="Cancel" />
    3740 </form>
  • apps/routerconsole/jsp/nav.jsp

    rf738a02 rab4f3008  
    1919 <a href="susidns/index.jsp">SusiDNS</a> |
    2020 <a href="syndie/">Syndie</a> |
     21 <a href="http://localhost:7658/">My Eepsite</a> <br>
    2122 <a href="i2ptunnel/index.jsp">I2PTunnel</a> |
    2223 <a href="tunnels.jsp">Tunnels</a> |
     
    2425 <a href="netdb.jsp">NetDB</a> |
    2526 <a href="logs.jsp">Logs</a> |
     27 <a href="jobs.jsp">Jobs</a> |
    2628 <a href="oldstats.jsp">Stats</a> |
    2729 <a href="oldconsole.jsp">Internals</a>
  • apps/routerconsole/jsp/summary.jsp

    rf738a02 rab4f3008  
    7373 <jsp:getProperty name="helper" property="destinations" />
    7474 
    75  <u><b>Tunnels</b></u><br />
    76  <b>Inbound:</b> <jsp:getProperty name="helper" property="inboundTunnels" /><br />
    77  <b>Outbound:</b> <jsp:getProperty name="helper" property="outboundTunnels" /><br />
     75 <u><b>Tunnels in/out</b></u><br />
     76 <b>Exploratory:</b> <jsp:getProperty name="helper" property="inboundTunnels" />/<jsp:getProperty name="helper" property="outboundTunnels" /><br />
     77 <b>Client:</b> <jsp:getProperty name="helper" property="inboundClientTunnels" />/<jsp:getProperty name="helper" property="outboundClientTunnels" /><br />
    7878 <b>Participating:</b> <jsp:getProperty name="helper" property="participatingTunnels" /><br />
    7979 <hr />
  • history.txt

    rf738a02 rab4f3008  
    1 $Id: history.txt,v 1.350 2005/12/07 19:50:35 jrandom Exp $
     1$Id: history.txt,v 1.351 2005/12/08 15:53:43 jrandom Exp $
     2
     32005-12-09  zzz
     4    * Create different strategies for exploratory tunnels (which are difficult
     5      to create) and client tunnels (which are much easier)
     6    * Gradually increase number of parallel build attempts as tunnel expiry
     7      nears.
     8    * Temporarily shorten attempted build tunnel length if builds using
     9      configured tunnel length are unsuccessful
     10    * React more aggressively to tunnel failure than routine tunnel
     11      replacement
     12    * Make tunnel creation times randomized - there is existing code to
     13      randomize the tunnels but it isn't effective due to the tunnel creation
     14      strategy. Currently, most tunnels get built all at once, at about 2 1/2
     15      to 3 minutes before expiration. The patch fixes this by fixing the
     16      randomization, and by changing the overlap time (with old tunnels) to a
     17      range of 2 to 4 minutes.
     18    * Reduce number of excess tunnels. Lots of excess tunnels get created due
     19      to overlapping calls. Just about anything generated a call which could
     20      build many tunnels all at once, even if tunnel building was already in
     21      process.
     22    * Miscellaneous router console enhancements
    223
    3242005-12-08  jrandom
  • router/java/src/net/i2p/router/RouterVersion.java

    rf738a02 rab4f3008  
    1616 */
    1717public class RouterVersion {
    18     public final static String ID = "$Revision: 1.307 $ $Date: 2005/12/01 12:16:54 $";
     18    public final static String ID = "$Revision: 1.308 $ $Date: 2005/12/08 15:53:41 $";
    1919    public final static String VERSION = "0.6.1.7";
    20     public final static long BUILD = 1;
     20    public final static long BUILD = 2;
    2121    public static void main(String args[]) {
    2222        System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
  • router/java/src/net/i2p/router/RouterWatchdog.java

    rf738a02 rab4f3008  
    9191    public void monitorRouter() {
    9292        boolean ok = verifyJobQueueLiveliness();
    93         ok = ok && verifyClientLiveliness();
     93        // If we aren't connected to the network that's why there's nobody to talk to
     94        int netErrors = (int) _context.statManager().getRate("udp.sendException").getRate(60*1000).getLastEventCount();
     95        ok = ok && (verifyClientLiveliness() || netErrors >= 5);
    9496       
    9597        if (!ok) {
  • router/java/src/net/i2p/router/TunnelManagerFacade.java

    rf738a02 rab4f3008  
    4949    /** how many outbound tunnels do we have available? */
    5050    public int getOutboundTunnelCount();
     51    /** how many free inbound client tunnels do we have available? */
     52    public int getInboundClientTunnelCount();
     53    /** how many outbound client tunnels do we have available? */
     54    public int getOutboundClientTunnelCount();
    5155   
    5256    /** When does the last tunnel we are participating in expire? */
     
    8286    public int getFreeTunnelCount() { return 0; }
    8387    public int getOutboundTunnelCount() { return 0; }
     88    public int getInboundClientTunnelCount() { return 0; }
     89    public int getOutboundClientTunnelCount() { return 0; }
    8490    public long getLastParticipatingExpiration() { return -1; }
    8591    public void buildTunnels(Destination client, ClientTunnelSettings settings) {}
  • router/java/src/net/i2p/router/TunnelPoolSettings.java

    rf738a02 rab4f3008  
    1919    private int _length;
    2020    private int _lengthVariance;
     21    private int _lengthOverride;
    2122    private boolean _isInbound;
    2223    private boolean _isExploratory;
     
    5556        _length = DEFAULT_LENGTH;
    5657        _lengthVariance = DEFAULT_LENGTH_VARIANCE;
     58        _lengthOverride = 0;
    5759        _allowZeroHop = DEFAULT_ALLOW_ZERO_HOP;
    5860        _isInbound = false;
     
    9193    public int getLengthVariance() { return _lengthVariance; }
    9294    public void setLengthVariance(int variance) { _lengthVariance = variance; }
     95
     96    /* Set to a nonzero value to override the length setting */
     97    public int getLengthOverride() { return _lengthOverride; }
     98    public void setLengthOverride(int variance) { _lengthOverride = variance; }
    9399   
    94100    /** is this an inbound tunnel? */
  • router/java/src/net/i2p/router/tunnel/pool/ExpireJob.java

    rf738a02 rab4f3008  
    2626            }
    2727        } else {
    28             if (_pool.getSettings().isInbound()) {
    29                 return "Expire client inbound tunnel";
    30             } else {
    31                 return "Expire client outbound tunnel";
    32             }
     28            StringBuffer rv = new StringBuffer(32);
     29            if (_pool.getSettings().isInbound())
     30                rv.append("Expire inbound client tunnel for ");
     31            else
     32                rv.append("Expire outbound client tunnel for ");
     33            if (_pool.getSettings().getDestinationNickname() != null)
     34                rv.append(_pool.getSettings().getDestinationNickname());
     35            else
     36                rv.append(_pool.getSettings().getDestination().toBase64().substring(0,4));
     37            return rv.toString();
    3338        }
    3439    }
  • router/java/src/net/i2p/router/tunnel/pool/RebuildJob.java

    rf738a02 rab4f3008  
    88 * Build a new tunnel to replace the existing one before it expires.  This job
    99 * should be removed (or scheduled to run immediately) if the tunnel fails.
    10  *
     10 * If an exploratory tunnel build at a random time between 3 1/2 and 4 minutes early;
     11 * else if only one tunnel in pool build 4 minutes early;
     12 * otherwise build at a random time between 2 and 4 minutes early.
     13 * Five build attempts in parallel if an exploratory tunnel.
    1114 */
    1215class RebuildJob extends JobImpl {
     
    1821        _pool = pool;
    1922        _cfg = cfg;
    20         long rebuildOn = cfg.getExpiration() - pool.getSettings().getRebuildPeriod();
    21         rebuildOn -= ctx.random().nextInt(pool.getSettings().getRebuildPeriod()*2);
     23        long rebuildOn;
     24        if (_pool.getSettings().isExploratory()) {
     25            rebuildOn = cfg.getExpiration() - (((pool.getSettings().getRebuildPeriod() * 7) / 2));
     26            rebuildOn -= ctx.random().nextInt(pool.getSettings().getRebuildPeriod() / 2);
     27        } else if ((pool.getSettings().getQuantity() + pool.getSettings().getBackupQuantity()) == 1) {
     28            rebuildOn = cfg.getExpiration() - (pool.getSettings().getRebuildPeriod() * 4);
     29        } else {
     30            rebuildOn = cfg.getExpiration() - (pool.getSettings().getRebuildPeriod() * 2);
     31            rebuildOn -= ctx.random().nextInt(pool.getSettings().getRebuildPeriod() * 2);
     32        }
    2233        getTiming().setStartAfter(rebuildOn);
    2334    }
    24     public String getName() { return "Rebuild tunnel"; }
     35    public String getName() {
     36        if (_pool.getSettings().isExploratory()) {
     37            if (_pool.getSettings().isInbound()) {
     38                return "Rebuild exploratory inbound tunnel";
     39            } else {
     40                return "Rebuild exploratory outbound tunnel";
     41            }
     42        } else {
     43            StringBuffer rv = new StringBuffer(32);
     44            if (_pool.getSettings().isInbound())
     45                rv.append("Rebuild inbound client tunnel for ");
     46            else
     47                rv.append("Rebuild outbound client tunnel for ");
     48            if (_pool.getSettings().getDestinationNickname() != null)
     49                rv.append(_pool.getSettings().getDestinationNickname());
     50            else
     51                rv.append(_pool.getSettings().getDestination().toBase64().substring(0,4));
     52            return rv.toString();
     53        }
     54    }
    2555    public void runJob() {
    26         _pool.refreshBuilders();
     56        if (_pool.getSettings().isExploratory())
     57            _pool.refreshBuilders(4, 4);
     58        else
     59            _pool.refreshBuilders(1, 4);
    2760    }
    2861}
  • router/java/src/net/i2p/router/tunnel/pool/RequestTunnelJob.java

    rf738a02 rab4f3008  
    6767        ctx.statManager().createRateStat("tunnel.receiveRejectionCritical", "How often we are rejected due to critical failure?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
    6868        ctx.statManager().createRateStat("tunnel.buildFailure", "What hop was being requested when a nonexploratory tunnel request failed?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
    69         ctx.statManager().createRateStat("tunnel.buildExploratoryFailure", "What hop was beiing requested when an exploratory tunnel request failed?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     69        ctx.statManager().createRateStat("tunnel.buildExploratoryFailure", "What hop was being requested when an exploratory tunnel request failed?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     70        ctx.statManager().createRateStat("tunnel.buildExploratoryFailure1Hop", "What hop was being requested when a 1 hop exploratory tunnel request failed?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     71        ctx.statManager().createRateStat("tunnel.buildExploratoryFailure2Hop", "What hop was being requested when a 2 hop exploratory tunnel request failed?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     72        ctx.statManager().createRateStat("tunnel.buildExploratoryFailure3Hop", "What hop was being requested when a 3 hop exploratory tunnel request failed?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
    7073        ctx.statManager().createRateStat("tunnel.buildSuccess", "How often we succeed building a non-exploratory tunnel?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
    7174        ctx.statManager().createRateStat("tunnel.buildExploratorySuccess", "How often we succeed building an exploratory tunnel?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     75        ctx.statManager().createRateStat("tunnel.buildExploratorySuccess1Hop", "How often we succeed building a 1 hop exploratory tunnel?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     76        ctx.statManager().createRateStat("tunnel.buildExploratorySuccess2Hop", "How often we succeed building a 2 hop exploratory tunnel?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     77        ctx.statManager().createRateStat("tunnel.buildExploratorySuccess3Hop", "How often we succeed building a 3 hop exploratory tunnel?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
    7278        ctx.statManager().createRateStat("tunnel.buildPartialTime", "How long a non-exploratory request took to be accepted?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
    7379        ctx.statManager().createRateStat("tunnel.buildExploratoryPartialTime", "How long an exploratory request took to be accepted?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     
    264270        if (_onFailed != null)
    265271            getContext().jobQueue().addJob(_onFailed);
    266         if (_isExploratory)
    267             getContext().statManager().addRateData("tunnel.buildExploratoryFailure", _currentHop, _config.getLength());
    268         else
     272        if (_isExploratory) {
     273            int i = _config.getLength();
     274            getContext().statManager().addRateData("tunnel.buildExploratoryFailure", _currentHop, i);
     275            if (i == 2)
     276                getContext().statManager().addRateData("tunnel.buildExploratoryFailure1Hop", _currentHop, i);
     277            else if (i == 3)
     278                getContext().statManager().addRateData("tunnel.buildExploratoryFailure2Hop", _currentHop, i);
     279            else if (i == 4)
     280                getContext().statManager().addRateData("tunnel.buildExploratoryFailure3Hop", _currentHop, i);
     281        } else
    269282            getContext().statManager().addRateData("tunnel.buildFailure", _currentHop, _config.getLength());
    270283    }
     
    285298            if (_onCreated != null)
    286299                getContext().jobQueue().addJob(_onCreated);
    287             if (_isExploratory)
     300            if (_isExploratory) {
     301                int i = _config.getLength();
    288302                getContext().statManager().addRateData("tunnel.buildExploratorySuccess", 1, 0);
    289             else
     303                if (i == 2)
     304                    getContext().statManager().addRateData("tunnel.buildExploratorySuccess1Hop", 1, 0);
     305                else if (i == 3)
     306                    getContext().statManager().addRateData("tunnel.buildExploratorySuccess2Hop", 1, 0);
     307                else if (i == 4)
     308                    getContext().statManager().addRateData("tunnel.buildExploratorySuccess3Hop", 1, 0);
     309            } else
    290310                getContext().statManager().addRateData("tunnel.buildSuccess", 1, 0);
    291311        }
  • router/java/src/net/i2p/router/tunnel/pool/TunnelBuilder.java

    rf738a02 rab4f3008  
    111111            // yikes, nothing left, lets get some backup (if we're allowed)
    112112            _pool.getManager().buildComplete();
    113             _pool.refreshBuilders();
     113            _pool.refreshBuilders(1, 4);
    114114        }
    115115    }
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java

    rf738a02 rab4f3008  
    2727    protected int getLength(RouterContext ctx, TunnelPoolSettings settings) {
    2828        int length = settings.getLength();
    29         if (settings.getLengthVariance() != 0) {
     29        int override = settings.getLengthOverride();
     30        if (override != 0)
     31            length = override;
     32        else if (settings.getLengthVariance() != 0) {
    3033            int skew = settings.getLengthVariance();
    3134            if (skew > 0)
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java

    rf738a02 rab4f3008  
    3838   
    3939    /**
    40      * Only 5 builds per minute per pool, even if we have failing tunnels,
     40     * Only 10 builds per minute per pool, even if we have failing tunnels,
    4141     * etc.  On overflow, the necessary additional tunnels are built by the
    4242     * RefreshJob
     
    6666        _refreshJob.getTiming().setStartAfter(_context.clock().now() + 60*1000);
    6767        _context.jobQueue().addJob(_refreshJob);
    68         int added = refreshBuilders();
     68        int added = refreshBuilders(0, 0);
    6969        if (added <= 0) {
    7070            // we just reconnected and didn't require any new tunnel builders.
     
    8686    }
    8787
    88     private int countUsableTunnels() {
     88    /**
     89     * Return number of tunnels expiring greater than
     90     * timeFactor * RebuildPeriod from now
     91     *
     92     */
     93    private int countUsableTunnels(int timeFactor) {
    8994        int valid = 0;
    9095        synchronized (_tunnels) {
    9196            for (int i = 0; i < _tunnels.size(); i++) {
    9297                TunnelInfo info = (TunnelInfo)_tunnels.get(i);
    93                 if (info.getExpiration() > _context.clock().now() + 3*_settings.getRebuildPeriod())
     98                if (info.getExpiration() > _context.clock().now() + (timeFactor * _settings.getRebuildPeriod()))
    9499                    valid++;
    95100            }
     
    100105    /**
    101106     * Fire up as many buildTunnel tasks as necessary, returning how many
    102      * were added
    103      *
    104      */
    105     int refreshBuilders() {
     107     * were added.
     108     * Build maxBuild tunnels (0 = unlimited), use timeFactor * RebuildPeriod.
     109     * Fire off up to six extra jobs if an exploratory tunnel is
     110     * requested by RebuildJob or tunnelFailed (maxBuild > 1).
     111     * Throttle builds to a maximum per minute; reduce maximum if job lag is high,
     112     * or if we have network errors which indicate we are disconnected from the network.
     113     * Override pool length setting and build a 1-hop tunnel if time is short.
     114     *
     115     */
     116    int refreshBuilders(int maxBuild, int timeFactor) {
    106117        if ( (_settings.getDestination() != null) && (!_context.clientManager().isLocal(_settings.getDestination())) )
    107118            _alive = false;
    108119        if (!_alive) return 0;
    109120        // only start up new build tasks if we need more of 'em
    110         int target = _settings.getQuantity() + _settings.getBackupQuantity();
    111         int usableTunnels = countUsableTunnels();
    112        
    113         if ( (target > usableTunnels) && (_log.shouldLog(Log.INFO)) )
    114             _log.info(toString() + ": refreshing builders, previously had " + usableTunnels
     121        int baseTarget = _settings.getQuantity() + _settings.getBackupQuantity();
     122        int target = baseTarget;
     123        int usableTunnels = countUsableTunnels(timeFactor);
     124        if (_settings.isExploratory() && target > 0 && maxBuild > 1)
     125            target+= 6;
     126       
     127        if ( (target > usableTunnels)  )
     128            if ( (target > usableTunnels) && (_log.shouldLog(Log.INFO)) )
     129                _log.info(toString() + ": refreshing builders, previously had " + usableTunnels
    115130                          + ", want a total of " + target + ", creating "
    116                           + (target-usableTunnels) + " new ones.");
     131                          + (target-usableTunnels) + " new ones (" + maxBuild + " max).");
    117132
    118133        if (target > usableTunnels) {
     
    124139            }
    125140            int build = (target - usableTunnels);
    126             if (build > (MAX_BUILDS_PER_MINUTE - _buildsThisMinute))
    127                 build = (MAX_BUILDS_PER_MINUTE - _buildsThisMinute);
    128            
     141            if (maxBuild > 0 && build > maxBuild)
     142                build = maxBuild;
     143            int buildThrottle = MAX_BUILDS_PER_MINUTE;
     144            int lag = (int) _context.statManager().getRate("jobQueue.jobLag").getRate(60*1000).getAverageValue();
     145            int netErrors = (int) _context.statManager().getRate("udp.sendException").getRate(60*1000).getLastEventCount();
     146            if (lag > 3 * 1000 || netErrors > 5) {
     147                if (_log.shouldLog(Log.WARN))
     148                    _log.warn("Throttling tunnel builds lag = " + lag + "; net errors = " + netErrors);
     149                if (_settings.isExploratory())
     150                    buildThrottle = 3;
     151                else
     152                    buildThrottle = 1;
     153            } else if (lag > 1 * 1000) {
     154                if (_settings.isExploratory())
     155                    buildThrottle = 5;
     156                else
     157                    buildThrottle = 2;
     158            }
     159            if (build > (buildThrottle - _buildsThisMinute))
     160                build = (buildThrottle - _buildsThisMinute);
     161            if (build <= 0) return 0;
     162
     163            if ((_settings.isExploratory() && baseTarget > countUsableTunnels(1)) ||
     164                ((!_settings.isExploratory()) && baseTarget > countUsableTunnels(0)))
     165                    _settings.setLengthOverride(1);
     166                else
     167                    _settings.setLengthOverride(0);
     168
    129169            int wanted = build;
    130170            build = _manager.allocateBuilds(build);
     
    256296            if (_log.shouldLog(Log.INFO))
    257297                _log.info(toString() + ": Settings updated on the pool: " + settings);
    258             refreshBuilders(); // to start/stop new sequences, in case the quantities changed
     298            refreshBuilders(1, 4); // to start/stop new sequences, in case the quantities changed
    259299        }
    260300    }
     
    279319        if (ls != null)
    280320            _context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
    281        
    282         refreshBuilders();
    283321    }
    284322   
     
    320358            return;
    321359        }
    322         refreshBuilders();
    323360    }
    324361
     
    344381            if (ls != null) {
    345382                _context.clientManager().requestLeaseSet(_settings.getDestination(), ls);
     383                if (_settings.isExploratory())
     384                    refreshBuilders(3, 4);
     385                else
     386                    refreshBuilders(1, 4);
    346387            } else {
    347388                if (_log.shouldLog(Log.WARN))
     
    349390                              + " remaining), request a new tunnel");
    350391                if (remaining < _settings.getBackupQuantity() + _settings.getQuantity())
    351                     buildFallback();
    352             }
    353         }
    354         refreshBuilders();
     392                    if (!buildFallback())
     393                        if (_settings.isExploratory())
     394                            refreshBuilders(3, 4);
     395                        else
     396                            refreshBuilders(1, 4);
     397            }
     398        } else {
     399            if (_settings.isExploratory())
     400                refreshBuilders(3, 4);
     401            else
     402                refreshBuilders(1, 4);
     403        }
    355404    }
    356405
     
    378427    }
    379428
    380     void buildFallback() {
     429    /**
     430     * Return true if a fallback tunnel is built
     431     *
     432     */
     433    boolean buildFallback() {
    381434        int quantity = _settings.getBackupQuantity() + _settings.getQuantity();
    382         int usable = countUsableTunnels();
    383         if (usable >= quantity) return;
    384 
    385         if (_log.shouldLog(Log.INFO))
    386             _log.info(toString() + ": building a fallback tunnel (usable: " + usable + " needed: " + quantity + ")");
    387         if ( (usable == 0) && (_settings.getAllowZeroHop()) )
     435        int usable = countUsableTunnels(1);
     436        if (usable >= quantity) return false;
     437
     438        if ( (usable == 0) && (_settings.getAllowZeroHop()) ) {
     439            if (_log.shouldLog(Log.INFO))
     440                _log.info(toString() + ": building a fallback tunnel (usable: " + usable + " needed: " + quantity + ")");
    388441            _builder.buildTunnel(_context, this, true);
     442            return true;
     443        }
    389444        //else
    390445        //    _builder.buildTunnel(_context, this);
    391         refreshBuilders();
     446        return false;
    392447    }
    393448   
     
    477532            super(ctx);
    478533        }
    479         public String getName() { return "Refresh pool"; }
     534        public String getName() { return "Refresh " + TunnelPool.this.toString(); }
    480535        public void runJob() {
    481536            if (!_alive) return;
    482             int added = refreshBuilders();
     537            int added;
     538            if (_settings.isExploratory())
     539                added = refreshBuilders(0, 2);
     540            else
     541                added = refreshBuilders(0, 1);
    483542            if ( (added > 0) && (_log.shouldLog(Log.WARN)) )
    484                 _log.warn("Passive rebuilding a tunnel for " + TunnelPool.this.toString());
     543                _log.warn("Additional parallel rebuilding of tunnel for " + TunnelPool.this.toString());
    485544            requeue(30*1000);
    486545        }
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java

    rf738a02 rab4f3008  
    155155            return _outboundExploratory.size();
    156156    }
     157    public int getInboundClientTunnelCount() {
     158        int count = 0;
     159        List destinations = null;
     160        synchronized (_clientInboundPools) {
     161            destinations = new ArrayList(_clientInboundPools.keySet());
     162        }
     163        for (int i = 0; i < destinations.size(); i++) {
     164            Hash client = (Hash)destinations.get(i);
     165            TunnelPool pool = null;
     166            synchronized (_clientInboundPools) {
     167                pool = (TunnelPool)_clientInboundPools.get(client);
     168            }
     169            count += pool.listTunnels().size();
     170        }
     171        return count;
     172    }
     173    public int getOutboundClientTunnelCount() {
     174        int count = 0;
     175        List destinations = null;
     176        synchronized (_clientInboundPools) {
     177            destinations = new ArrayList(_clientOutboundPools.keySet());
     178        }
     179        for (int i = 0; i < destinations.size(); i++) {
     180            Hash client = (Hash)destinations.get(i);
     181            TunnelPool pool = null;
     182            synchronized (_clientOutboundPools) {
     183                pool = (TunnelPool)_clientOutboundPools.get(client);
     184            }
     185            count += pool.listTunnels().size();
     186        }
     187        return count;
     188    }
    157189    public int getParticipatingCount() { return _context.tunnelDispatcher().getParticipatingCount(); }
    158190    public long getLastParticipatingExpiration() { return _context.tunnelDispatcher().getLastParticipatingExpiration(); }
     
    241273        }
    242274        inbound.startup();
     275        try { Thread.sleep(3*1000); } catch (InterruptedException ie) {}
    243276        outbound.startup();
    244277    }
     
    317350        _inboundExploratory.startup();
    318351       
     352        try { Thread.sleep(3*1000); } catch (InterruptedException ie) {}
    319353        TunnelPoolSettings outboundSettings = new TunnelPoolSettings();
    320354        outboundSettings.setIsExploratory(true);
     
    407441            long timeLeft = cfg.getExpiration()-_context.clock().now();
    408442            if (timeLeft > 0)
    409                 out.write("<td>" + DataHelper.formatDuration(timeLeft) + "</td>");
    410             else
    411                 out.write("<td>(grace period)</td>");
    412             out.write("<td>" + cfg.getProcessedMessagesCount() + "KB</td>");
     443                out.write("<td align=right>" + DataHelper.formatDuration(timeLeft) + "</td>");
     444            else
     445                out.write("<td align=right>(grace period)</td>");
     446            out.write("<td align=right>" + cfg.getProcessedMessagesCount() + "KB</td>");
    413447            out.write("</tr>\n");
    414448            processed += cfg.getProcessedMessagesCount();
     
    442476            else
    443477                out.write("<tr><td><b>outbound</b></td>");
    444             out.write("<td>" + DataHelper.formatDuration(timeLeft) + "</td>\n");
    445             out.write("<td>" + info.getProcessedMessagesCount() + "KB</td>\n");
     478            out.write("<td align=right>" + DataHelper.formatDuration(timeLeft) + "</td>\n");
     479            out.write("<td align=right>" + info.getProcessedMessagesCount() + "KB</td>\n");
    446480            for (int j = 0; j < info.getLength(); j++) {
    447481                Hash peer = info.getPeer(j);
Note: See TracChangeset for help on using the changeset viewer.