forked from I2P_Developers/i2p.i2p
Console: Show smoothed receive BPS for SSU peers
Don't show zero send/receive BPS after 15 sec idle; show smoothed value, so display isn't mostly zeros. BPS sorters will now work correctly and totals are more accurate. Pass now to send/receive BPS methods and BW estimator Comment out UDPTransport.noteSend() Fix alignment issue in NTCP peers table Show 0 instead of 0.00 for zero BPS Change rounding mode of formatters
This commit is contained in:
@@ -3,6 +3,7 @@ package net.i2p.router.web.helpers;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Comparator;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
@@ -418,8 +419,8 @@ public class PeerHelper extends HelperBase {
|
||||
.append("\">").append(_t("Dir")).append("</a></th>" +
|
||||
"<th>").append(_t("IPv6")).append("</th>" +
|
||||
"<th>").append(_t("Version")).append("</th>" +
|
||||
"<th align=\"right\"><a href=\"#def.idle\">").append(_t("Idle")).append("</a></th>" +
|
||||
"<th align=\"right\"><a href=\"#def.rate\">").append(_t("In/Out")).append("</a></th>" +
|
||||
"<th><a href=\"#def.idle\">").append(_t("Idle")).append("</a></th>" +
|
||||
"<th><a href=\"#def.rate\">").append(_t("In/Out")).append("</a></th>" +
|
||||
"<th align=\"right\"><a href=\"#def.up\">").append(_t("Up")).append("</a></th>" +
|
||||
"<th align=\"right\"><a href=\"#def.skew\">").append(_t("Skew")).append("</a></th>" +
|
||||
"<th align=\"right\"><a href=\"#def.recv\">").append(_t("RX")).append("</a></th>" +
|
||||
@@ -518,8 +519,13 @@ public class PeerHelper extends HelperBase {
|
||||
}
|
||||
|
||||
private static final NumberFormat _rateFmt = new DecimalFormat("#,##0.00");
|
||||
static {
|
||||
_rateFmt.setRoundingMode(RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private static String formatRate(float rate) {
|
||||
if (rate < 0.005f)
|
||||
return "0";
|
||||
synchronized (_rateFmt) { return _rateFmt.format(rate); }
|
||||
}
|
||||
|
||||
@@ -704,8 +710,8 @@ public class PeerHelper extends HelperBase {
|
||||
buf.append("<span class=\"left\">").append(DataHelper.formatDuration2(idleOut));
|
||||
buf.append("</span></td>");
|
||||
|
||||
int recvBps = (idleIn > 15*1000 ? 0 : peer.getReceiveBps());
|
||||
int sendBps = (idleOut > 15*1000 ? 0 : peer.getSendBps());
|
||||
int recvBps = peer.getReceiveBps(now);
|
||||
int sendBps = peer.getSendBps(now);
|
||||
|
||||
buf.append("<td class=\"cells\" align=\"center\" nowrap><span class=\"right\">");
|
||||
buf.append(formatKBps(recvBps));
|
||||
@@ -892,8 +898,13 @@ public class PeerHelper extends HelperBase {
|
||||
}
|
||||
|
||||
private static final DecimalFormat _fmt = new DecimalFormat("#,##0.00");
|
||||
static {
|
||||
_fmt.setRoundingMode(RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private static final String formatKBps(int bps) {
|
||||
if (bps < 5)
|
||||
return "0";
|
||||
synchronized (_fmt) {
|
||||
return _fmt.format((float)bps/1000);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.transport.udp.PeerState;
|
||||
|
||||
@@ -120,9 +121,11 @@ class UDPSorters {
|
||||
}
|
||||
|
||||
static class RateInComparator extends PeerComparator {
|
||||
private final long now = I2PAppContext.getGlobalContext().clock().now();
|
||||
|
||||
@Override
|
||||
public int compare(PeerState l, PeerState r) {
|
||||
int rv = l.getReceiveBps() - r.getReceiveBps();
|
||||
int rv = l.getReceiveBps(now) - r.getReceiveBps(now);
|
||||
if (rv == 0) // fallback on alpha
|
||||
return super.compare(l, r);
|
||||
else
|
||||
@@ -131,9 +134,11 @@ class UDPSorters {
|
||||
}
|
||||
|
||||
static class RateOutComparator extends PeerComparator {
|
||||
private final long now = I2PAppContext.getGlobalContext().clock().now();
|
||||
|
||||
@Override
|
||||
public int compare(PeerState l, PeerState r) {
|
||||
int rv = l.getSendBps() - r.getSendBps();
|
||||
int rv = l.getSendBps(now) - r.getSendBps(now);
|
||||
if (rv == 0) // fallback on alpha
|
||||
return super.compare(l, r);
|
||||
else
|
||||
|
||||
@@ -5598,12 +5598,10 @@ img+tt {
|
||||
|
||||
/* /peers */
|
||||
|
||||
#ntcpconnections th:nth-child(6),
|
||||
#ntcpconnections th:nth-child(7),
|
||||
#ntcpconnections th:nth-child(8),
|
||||
#ntcpconnections th:nth-child(9),
|
||||
#ntcpconnections th:nth-child(10),
|
||||
#ntcpconnections td:nth-child(6),
|
||||
#ntcpconnections td:nth-child(7),
|
||||
#ntcpconnections td:nth-child(8),
|
||||
#ntcpconnections td:nth-child(9),
|
||||
@@ -5624,7 +5622,6 @@ img+tt {
|
||||
#ntcpconnections .tablefooter td:nth-child(3),
|
||||
#ntcpconnections .tablefooter td:nth-child(4),
|
||||
#ntcpconnections .tablefooter td:nth-child(5),
|
||||
#ntcpconnections .tablefooter td:nth-child(6),
|
||||
#udpconnections .tablefooter td:nth-child(3),
|
||||
#udpconnections .tablefooter td:nth-child(4),
|
||||
#udpconnections .tablefooter td:nth-child(7),
|
||||
|
||||
@@ -25,7 +25,6 @@ import net.i2p.router.transport.udp.InboundMessageFragments.ModifiableLong;
|
||||
import net.i2p.router.util.CachedIteratorCollection;
|
||||
import net.i2p.router.util.CoDelPriorityBlockingQueue;
|
||||
import net.i2p.router.util.PriBlockingQueue;
|
||||
import net.i2p.util.BandwidthEstimator;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleTimer2;
|
||||
@@ -116,7 +115,7 @@ public class PeerState {
|
||||
/** how many bytes can we send to the peer in the current second */
|
||||
private int _sendWindowBytesRemaining;
|
||||
private final Object _sendWindowBytesRemainingLock = new Object();
|
||||
private final BandwidthEstimator _bwEstimator;
|
||||
private final SimpleBandwidthEstimator _bwEstimator;
|
||||
// smoothed value, for display only
|
||||
private int _receiveBps;
|
||||
private int _receiveBytes;
|
||||
@@ -640,13 +639,21 @@ public class PeerState {
|
||||
* The Westwood+ bandwidth estimate
|
||||
* @return the smoothed send transfer rate
|
||||
*/
|
||||
public int getSendBps() { return (int) (_bwEstimator.getBandwidthEstimate() * 1000); }
|
||||
public int getSendBps(long now) { return (int) (_bwEstimator.getBandwidthEstimate(now) * 1000); }
|
||||
|
||||
/**
|
||||
* An approximation, for display only
|
||||
* @return the smoothed receive transfer rate
|
||||
*/
|
||||
public synchronized int getReceiveBps() { return _receiveBps; }
|
||||
public synchronized int getReceiveBps(long now) {
|
||||
long duration = now - _receivePeriodBegin;
|
||||
if (duration >= 1000) {
|
||||
_receiveBps = (int)(0.9f*_receiveBps + 0.1f*(_receiveBytes * (1000f/duration)));
|
||||
_receiveBytes = 0;
|
||||
_receivePeriodBegin = now;
|
||||
}
|
||||
return _receiveBps;
|
||||
}
|
||||
|
||||
int incrementConsecutiveFailedSends() {
|
||||
synchronized(_outboundMessages) {
|
||||
@@ -870,7 +877,7 @@ public class PeerState {
|
||||
bwe = -1; // for log below
|
||||
} else {
|
||||
_sendWindowBytes = getVersion() == 2 ? PeerState2.MAX_MTU : (isIPv6() ? MAX_IPV6_MTU : LARGE_MTU);
|
||||
bwe = _bwEstimator.getBandwidthEstimate();
|
||||
bwe = _bwEstimator.getBandwidthEstimate(now);
|
||||
_slowStartThreshold = Math.max( (int)(bwe * _rtt), 2 * _mtu);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,14 @@ class SimpleBandwidthEstimator implements BandwidthEstimator {
|
||||
* @return the current bandwidth estimate in bytes/ms.
|
||||
*/
|
||||
public float getBandwidthEstimate() {
|
||||
long now = _context.clock().now();
|
||||
return getBandwidthEstimate(_context.clock().now());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current bandwidth estimate in bytes/ms.
|
||||
* @since 0.9.58
|
||||
*/
|
||||
public float getBandwidthEstimate(long now) {
|
||||
// avoid deadlock
|
||||
int rtt = _state.getRTT();
|
||||
// anti-aliasing filter
|
||||
|
||||
@@ -3487,11 +3487,12 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Failed sending " + msg + " to " + msg.getPeer());
|
||||
}
|
||||
noteSend(msg, false);
|
||||
//noteSend(msg, false);
|
||||
if (m != null)
|
||||
super.afterSend(m, false);
|
||||
}
|
||||
|
||||
/*
|
||||
private void noteSend(OutboundMessageState msg, boolean successful) {
|
||||
// bail before we do all the work
|
||||
if (!_context.messageHistory().getDoLog())
|
||||
@@ -3529,6 +3530,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
(p != null ? p.getRemotePeer() : null), successful, buf.toString());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public void failed(OutNetMessage msg, String reason) {
|
||||
if (msg == null) return;
|
||||
@@ -3545,7 +3547,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (msg == null) return;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Sending message succeeded: " + msg);
|
||||
noteSend(msg, true);
|
||||
//noteSend(msg, true);
|
||||
OutNetMessage m = msg.getMessage();
|
||||
if (m != null)
|
||||
super.afterSend(m, true);
|
||||
|
||||
Reference in New Issue
Block a user