2006-03-01 jrandom

* More aggressive tunnel throttling as we approach our bandwidth limit,
      and throttle based off periods wider than 1 second.
    * Included Doubtful Salmon's syndie stylings (thanks!)
This commit is contained in:
jrandom
2006-03-01 23:01:20 +00:00
committed by zzz
parent 2b79e2df3f
commit 2c6d953359
6 changed files with 414 additions and 79 deletions

View File

@ -85,4 +85,360 @@ td.s_detail_summDetail {
td.s_summary_summ {
font-size: 0.8em;
background-color: #DDDDFF;
}
<!-- following are doubtful salmon's contributions -->
body {
margin : 0px;
padding : 0px;
width: 99%;
font-family : Arial, sans-serif, Helvetica;
background-color : #FFF;
color : black;
font-size : 100%;
/* we've avoided Tantek Hacks so far,
** but we can't avoid using the non-w3c method of
** box rendering. (and therefore one of mozilla's
** proprietry -moz properties (which hopefully they'll
** drop soon).
*/
-moz-box-sizing : border-box;
box-sizing : border-box;
}
a:link{color:#007}
a:visited{color:#606}
a:hover{color:#720}
a:active{color:#900}
select {
min-width: 1.5em;
}
.overallTable {
border-spacing: 0px;
border-collapse: collapse;
float: left;
}
.topNav {
background-color: #BBB;
}
.topNav_user {
text-align: left;
float: left;
display: inline;
}
.topNav_admin {
text-align: right;
float: right;
margin: 0 5px 0 0;
display: inline;
}
.controlBar {
margin: 0em;
padding: 0em;
// border: medium solid #DDF;
background-color: #EEF;
color: inherit;
font-size: small;
clear: left; /* fixes a bug in Opera */
}
.controlBarRight {
text-align: right;
}
.threadEven {
background-color: #FFF;
white-space: nowrap;
}
.threadOdd {
background-color: #FFC;
white-space: nowrap;
}
.threadLeft {
text-align: left;
align: left;
}
.threadNav {
background-color: #EEF;
border: medium solid #CCF;
}
.threadNavRight {
text-align: right;
float: right;
background-color: #EEF;
}
.rightOffset {
float: right;
margin: 0 5px 0 0;
display: inline;
}
.threadInfoLeft {
float: left;
margin: 5px 0px 0 0;
display: inline;
}
.threadInfoRight {
float: right;
margin: 0 5px 0 0;
display: inline;
}
.postMeta {
border-top: 1px solid black;
background-color: #FFB;
}
.postMetaSubject {
text-align: left;
font-size: large;
}
.postMetaLink {
text-align: right;
}
.postDetails {
background-color: #FFC;
}
.postReply {
background-color: #CCF;
}
.postReplyText {
background-color: #CCF;
}
.postReplyOptions {
background-color: #CCF;
}
.syndieBlogTopNav {
padding: 0.5em;
width: 98%;
border: medium solid #CCF;
background-color: #EEF;
font-size: small;
}
.syndieBlogTopNavUser {
text-align: left;
}
.syndieBlogTopNavAdmin {
text-align: right;
}
.syndieBlogHeader {
width: 100%;
font-size: 1.4em;
background-color: #000;
text-align: Left;
float: Left;
}
.syndieBlogHeader a {
color: #FFF;
padding: 4px;
}
.syndieBlogHeader a:hover {
color:#88F;
padding: 4px;
}
.syndieBlogLogo {
float: left;
display: inline;
}
.syndieBlogLinks {
width: 20%;
float: left;
}
.syndieBlogLinkGroup {
font-size: 0.8em;
background-color: #DDD;
border: 1px solid black;
margin: 5px;
padding: 2px;
}
.syndieBlogLinkGroup ul {
list-style: none;
}
.syndieBlogLinkGroup li {
}
.syndieBlogLinkGroupName {
font-weight: bold;
width: 100%;
border-bottom: 1px dashed black;
display: block;
}
.syndieBlogPostInfoGroup {
font-size: 0.8em;
background-color: #FFEA9F;
border: 1px solid black;
margin: 5px;
padding: 2px;
}
.syndieBlogPostInfoGroup ol {
list-style: none;
}
.syndieBlogPostInfoGroup li {
}
.syndieBlogPostInfoGroup li a {
display: block;
}
.syndieBlogPostInfoGroupName {
font-weight: bold;
width: 100%;
border-bottom: 1px dashed black;
display: block;
}
.syndieBlogMeta {
text-align: left;
font-size: 0.8em;
background-color: #DDD;
border: 1px solid black;
margin: 5px;
padding: 2px;
}
.syndieBlogBody {
width: 80%;
float: left;
}
.syndieBlogPost {
border: 1px solid black;
margin-top: 5px;
margin-right: 5px;
}
.syndieBlogPostHeader {
background-color: #FFB;
padding: 2px;
}
.syndieBlogPostSubject {
font-weight: bold;
}
.syndieBlogPostFrom {
text-align: right;
}
.syndieBlogPostSummary {
background-color: #FFF;
padding: 2px;
}
.syndieBlogPostDetails {
background-color: #FFC;
padding: 2px;
}
.syndieBlogNav {
text-align: center;
}
.syndieBlogComments {
border: none;
margin-top: 5px;
margin-left: 0px;
float: left;
}
.syndieBlogComments ul {
list-style: none;
margin-left: 10px;
}
.syndieBlogCommentInfoGroup {
font-size: 0.8em;
margin-right: 5px;
}
.syndieBlogCommentInfoGroup ol {
list-style: none;
}
.syndieBlogCommentInfoGroup li {
}
.syndieBlogCommentInfoGroup li a {
display: block;
}
.syndieBlogCommentInfoGroupName {
font-size: 0.8em;
font-weight: bold;
}
.syndieBlogFavorites {
float: left;
margin: 5px 0px 0 0;
display: inline;
}
.syndieBlogList {
float: right;
margin: 5px 0px 0 0;
display: inline;
}
.b_topnavUser {
text-align: right;
background-color: #CCD;
}
.b_topnavHome {
background-color: #CCD;
color: #000;
width: 50px;
text-align: left;
}
.b_topnav {
background-color: #CCD;
}
.b_content {
}
.s_summary_overall {
}
.s_detail_overall {
}
.s_detail_subject {
font-size: 0.8em;
text-align: left;
background-color: #CCF;
}
.s_detail_quote {
margin-left: 1em;
border: 1px solid #DBDBDB;
background-color: #E0E0E0;
}
.s_detail_italic {
font-style: italic;
}
.s_detail_bold {
font-style: normal;
font-weight: bold;
}
.s_detail_underline {
font-style: normal;
text-decoration: underline;
}
.s_detail_meta {
font-size: 0.8em;
text-align: right;
background-color: #CCF;
}
.s_summary_subject {
font-size: 0.8em;
text-align: left;
background-color: #CCF;
}
.s_summary_meta {
font-size: 0.8em;
text-align: right;
background-color: #CCF;
}
.s_summary_quote {
margin-left: 1em;
border-width: 1px solid #DBDBDB;
background-color: #E0E0E0;
}
.s_summary_italic {
font-style: italic;
}
.s_summary_bold {
font-style: normal;
font-weight: bold;
}
.s_summary_underline {
font-style: normal;
text-decoration: underline;
}
.s_summary_summDetail {
font-size: 0.8em;
}
.s_detail_summDetail {
}
.s_detail_summDetailBlog {
}
.s_detail_summDetailBlogLink {
}
td.s_detail_summDetail {
background-color: #CCF;
}
td.s_summary_summ { width: 80%;
font-size: 0.8em;
background-color: #CCF;
}

View File

@ -1,4 +1,9 @@
$Id: history.txt,v 1.422 2006/02/27 14:05:41 jrandom Exp $
$Id: history.txt,v 1.423 2006/02/27 22:55:18 zzz Exp $
2006-03-01 jrandom
* More aggressive tunnel throttling as we approach our bandwidth limit,
and throttle based off periods wider than 1 second.
* Included Doubtful Salmon's syndie stylings (thanks!)
2006-02-27 zzz
* Update error page templates to add \r, Connection: close, and

View File

@ -1016,12 +1016,26 @@ class CoalesceStatsJob extends JobImpl {
super(ctx);
ctx.statManager().createRateStat("bw.receiveBps", "How fast we receive data (in KBps)", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("bw.sendBps", "How fast we send data (in KBps)", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("bw.sendRate", "Low level bandwidth send rate, averaged every minute", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("bw.recvRate", "Low level bandwidth receive rate, averaged every minute", "Bandwidth", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
ctx.statManager().createRateStat("router.activePeers", "How many peers we are actively talking with", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
ctx.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
}
public String getName() { return "Coalesce stats"; }
public void runJob() {
int active = getContext().commSystem().countActivePeers();
getContext().statManager().addRateData("router.activePeers", active, 60*1000);
int fast = getContext().profileOrganizer().countFastPeers();
getContext().statManager().addRateData("router.fastPeers", fast, 60*1000);
int highCap = getContext().profileOrganizer().countHighCapacityPeers();
getContext().statManager().addRateData("router.highCapacityPeers", highCap, 60*1000);
getContext().statManager().addRateData("bw.sendRate", (long)getContext().bandwidthLimiter().getSendBps(), 0);
getContext().statManager().addRateData("bw.recvRate", (long)getContext().bandwidthLimiter().getReceiveBps(), 0);
getContext().statManager().coalesceStats();
RateStat receiveRate = getContext().statManager().getRate("transport.receiveMessageSize");
@ -1043,16 +1057,7 @@ class CoalesceStatsJob extends JobImpl {
getContext().statManager().addRateData("bw.sendBps", (long)KBps, 60*1000);
}
}
int active = getContext().commSystem().countActivePeers();
getContext().statManager().addRateData("router.activePeers", active, 60*1000);
int fast = getContext().profileOrganizer().countFastPeers();
getContext().statManager().addRateData("router.fastPeers", fast, 60*1000);
int highCap = getContext().profileOrganizer().countHighCapacityPeers();
getContext().statManager().addRateData("router.highCapacityPeers", highCap, 60*1000);
requeue(60*1000);
}
}

View File

@ -88,36 +88,8 @@ class RouterThrottleImpl implements RouterThrottle {
}
long lag = _context.jobQueue().getMaxLag();
/*
RateStat rs = _context.statManager().getRate("router.throttleNetworkCause");
Rate r = null;
if (rs != null)
r = rs.getRate(60*1000);
long throttleEvents = (r != null ? r.getCurrentEventCount() + r.getLastEventCount() : 0);
if (throttleEvents > THROTTLE_EVENT_LIMIT) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Refusing tunnel request with the job lag of " + lag
+ " since there have been " + throttleEvents
+ " throttle events in the last 15 minutes or so");
_context.statManager().addRateData("router.throttleTunnelCause", lag, lag);
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
*/
RateStat rs = _context.statManager().getRate("transport.sendProcessingTime");
Rate r = null;
/*
if (rs != null)
r = rs.getRate(1*60*1000);
double processTime = (r != null ? r.getAverageValue() : 0);
if (processTime > 2000) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Refusing tunnel request with the job lag of " + lag
+ "since the 10 minute message processing time is too slow (" + processTime + ")");
_context.statManager().addRateData("router.throttleTunnelProcessingTime10m", (long)processTime, (long)processTime);
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
*/
if (rs != null)
r = rs.getRate(60*1000);
double processTime = (r != null ? r.getAverageValue() : 0);
@ -129,27 +101,6 @@ class RouterThrottleImpl implements RouterThrottle {
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
/*
rs = _context.statManager().getRate("transport.sendMessageFailureLifetime");
r = null;
if (rs != null)
r = rs.getRate(60*1000);
double failCount = (r != null ? r.getCurrentEventCount() + r.getLastEventCount() : 0);
if (failCount > 100) {
long periods = r.getLifetimePeriods();
long maxFailCount = r.getExtremeEventCount();
if ( (periods > 0) && (maxFailCount > 100) ) {
if (_context.random().nextInt((int)maxFailCount) <= failCount) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Refusing tunnel request with the job lag of " + lag
+ "since the 1 minute message failure count is too high (" + failCount + "/" + maxFailCount + ")");
_context.statManager().addRateData("router.throttleTunnelFailCount1m", (long)failCount, (long)maxFailCount);
return TunnelHistory.TUNNEL_REJECT_TRANSIENT_OVERLOAD;
}
}
}
*/
int numTunnels = _context.tunnelManager().getParticipatingCount();
if (numTunnels > getMinThrottleTunnels()) {
@ -244,9 +195,7 @@ class RouterThrottleImpl implements RouterThrottle {
double messagesPerTunnel = (r != null ? r.getAverageValue() : 0d);
if (messagesPerTunnel < DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE)
messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
int participatingTunnels = (r != null ? (int) (r.getLastEventCount() + r.getCurrentEventCount()) : 0);
if (participatingTunnels <= 0)
participatingTunnels = _context.tunnelManager().getParticipatingCount();
int participatingTunnels = _context.tunnelManager().getParticipatingCount();
double bytesAllocated = messagesPerTunnel * participatingTunnels * 1024;
if (!allowTunnel(bytesAllocated, numTunnels)) {
@ -261,6 +210,32 @@ class RouterThrottleImpl implements RouterThrottle {
+ " tunnels with lag of " + lag + ")");
return TUNNEL_ACCEPT;
}
private int get1sRate() {
return (int)Math.max(_context.bandwidthLimiter().getSendBps(), _context.bandwidthLimiter().getReceiveBps());
}
private int get1mRate() {
int send = 0;
RateStat rs = _context.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(1*60*1000).getAverageValue();
int recv = 0;
rs = _context.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(1*60*1000).getAverageValue();
return Math.max(send, recv);
}
private int get5mRate() {
int send = 0;
RateStat rs = _context.statManager().getRate("bw.sendRate");
if (rs != null)
send = (int)rs.getRate(5*60*1000).getAverageValue();
int recv = 0;
rs = _context.statManager().getRate("bw.recvRate");
if (rs != null)
recv = (int)rs.getRate(5*60*1000).getAverageValue();
return Math.max(send, recv);
}
private static final int DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE = 600; // 1KBps
@ -272,14 +247,17 @@ class RouterThrottleImpl implements RouterThrottle {
*/
private boolean allowTunnel(double bytesAllocated, int numTunnels) {
int maxKBps = Math.min(_context.bandwidthLimiter().getOutboundKBytesPerSecond(), _context.bandwidthLimiter().getInboundKBytesPerSecond());
int used = (int)Math.max(_context.bandwidthLimiter().getSendBps(), _context.bandwidthLimiter().getReceiveBps());
int used1s = get1sRate();
int used1m = get1mRate();
int used5m = get5mRate();
int used = Math.max(Math.max(used1s, used1m), used5m);
int availBps = (int)(((maxKBps*1024) - used) * getSharePercentage());
_context.statManager().addRateData("router.throttleTunnelBytesUsed", used, maxKBps);
_context.statManager().addRateData("router.throttleTunnelBytesAllowed", availBps, (long)bytesAllocated);
if (maxKBps <= 8) {
// lets be more conservative for dialup users and assume 1KBps per tunnel
if (availBps <= 8*1024) {
// lets be more conservative for people near their limit and assume 1KBps per tunnel
return ( (numTunnels + 1)*1024 < availBps);
}
@ -295,8 +273,8 @@ class RouterThrottleImpl implements RouterThrottle {
+ "Bps/" + allocatedKBps + "KBps allocated through " + numTunnels + " tunnels");
return true;
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Rejecting the tunnel w/ " + pctFull + " of our " + availBps
if (_log.shouldLog(Log.WARN))
_log.warn("Rejecting the tunnel w/ " + pctFull + " of our " + availBps
+ "Bps allowed (" + toAllocate + "bytes / " + allocatedKBps
+ "KBps) through " + numTunnels + " tunnels");
return false;

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.363 $ $Date: 2006/02/27 14:05:40 $";
public final static String ID = "$Revision: 1.364 $ $Date: 2006/02/27 22:55:19 $";
public final static String VERSION = "0.6.1.12";
public final static long BUILD = 1;
public final static long BUILD = 2;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -47,7 +47,6 @@ public class FIFOBandwidthLimiter {
private long _lastTotalSent;
private long _lastTotalReceived;
private long _lastStatsUpdated;
private long _lastRateUpdated;
private float _sendBps;
private float _recvBps;
@ -65,8 +64,6 @@ public class FIFOBandwidthLimiter {
_context.statManager().createRateStat("bwLimiter.pendingInboundRequests", "How many inbound requests are ahead of the current one (ignoring ones with 0)?", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bwLimiter.outboundDelayedTime", "How long it takes to honor an outbound request (ignoring ones with that go instantly)?", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bwLimiter.inboundDelayedTime", "How long it takes to honor an inbound request (ignoring ones with that go instantly)?", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bw.sendRate", "Low level bandwidth send rate, averaged every minute", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_context.statManager().createRateStat("bw.recvRate", "Low level bandwidth receive rate, averaged every minute", "BandwidthLimiter", new long[] { 60*1000l, 5*60*1000l, 10*60*1000l, 60*60*1000l });
_pendingInboundRequests = new ArrayList(16);
_pendingOutboundRequests = new ArrayList(16);
_lastTotalSent = _totalAllocatedOutboundBytes;
@ -74,7 +71,6 @@ public class FIFOBandwidthLimiter {
_sendBps = 0;
_recvBps = 0;
_lastStatsUpdated = now();
_lastRateUpdated = _lastStatsUpdated;
_refiller = new FIFOBandwidthRefiller(_context, this);
I2PThread t = new I2PThread(_refiller);
t.setName("BWRefiller" + (++__id));
@ -295,11 +291,6 @@ public class FIFOBandwidthLimiter {
_context.statManager().getStatLog().addData("bw", "bw.recvBps1s", (long)_recvBps, recv);
}
}
if (60*1000 + _lastRateUpdated <= now) {
_lastRateUpdated = now;
_context.statManager().addRateData("bw.sendRate", (long)_sendBps, 0);
_context.statManager().addRateData("bw.recvRate", (long)_recvBps, 0);
}
}
/**