forked from I2P_Developers/i2p.i2p
SSU: Increase CoDel drop threshold at UDPSender queue
Increase min and max queue size Tweak stats Util: Allow creation of CoDel queues with non-default parameters New params are tentative, may be adjusted later
This commit is contained in:
@@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Git";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 5;
|
||||
public final static long BUILD = 6;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
||||
@@ -35,8 +35,10 @@ class UDPSender {
|
||||
// Queue needs to be big enough that we can compete with NTCP for
|
||||
// bandwidth requests, and so CoDel can work well.
|
||||
// When full, packets back up into the PacketPusher thread, pre-CoDel.
|
||||
private static final int MIN_QUEUE_SIZE = 64;
|
||||
private static final int MAX_QUEUE_SIZE = 384;
|
||||
private static final int MIN_QUEUE_SIZE = 128;
|
||||
private static final int MAX_QUEUE_SIZE = 768;
|
||||
private static final int CODEL_TARGET = 100;
|
||||
private static final int CODEL_INTERVAL = 500;
|
||||
|
||||
public UDPSender(RouterContext ctx, DatagramSocket socket, String name, SocketListener lsnr) {
|
||||
_context = ctx;
|
||||
@@ -44,7 +46,7 @@ class UDPSender {
|
||||
_log = ctx.logManager().getLog(UDPSender.class);
|
||||
long maxMemory = SystemVersion.getMaxMemory();
|
||||
int qsize = (int) Math.max(MIN_QUEUE_SIZE, Math.min(MAX_QUEUE_SIZE, maxMemory / (1024*1024)));
|
||||
_outboundQueue = new CoDelBlockingQueue<UDPPacket>(ctx, "UDP-Sender", qsize);
|
||||
_outboundQueue = new CoDelBlockingQueue<UDPPacket>(ctx, "UDP-Sender", qsize, CODEL_TARGET, CODEL_INTERVAL);
|
||||
_socket = socket;
|
||||
_runner = new Runner();
|
||||
_name = name;
|
||||
@@ -283,13 +285,13 @@ class UDPSender {
|
||||
if (throttleTime > 10)
|
||||
_context.statManager().addRateData("udp.sendBWThrottleTime", throttleTime, acquireTime - packet.getBegin());
|
||||
if (packet.getMarkedType() == 1)
|
||||
_context.statManager().addRateData("udp.sendACKTime", throttleTime, packet.getLifetime());
|
||||
_context.statManager().addRateData("udp.pushTime", packet.getLifetime(), packet.getLifetime());
|
||||
_context.statManager().addRateData("udp.sendPacketSize", size, packet.getLifetime());
|
||||
_context.statManager().addRateData("udp.sendACKTime", throttleTime);
|
||||
_context.statManager().addRateData("udp.pushTime", packet.getLifetime());
|
||||
_context.statManager().addRateData("udp.sendPacketSize", size);
|
||||
} catch (IOException ioe) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error sending to " + packet.getPacket().getAddress(), ioe);
|
||||
_context.statManager().addRateData("udp.sendException", 1, packet.getLifetime());
|
||||
_context.statManager().addRateData("udp.sendException", 1);
|
||||
if (_socket.isClosed()) {
|
||||
if (_keepRunning) {
|
||||
_keepRunning = false;
|
||||
|
||||
@@ -56,17 +56,17 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
|
||||
*
|
||||
* I2P: Raise to 15 due to multithreading environment
|
||||
*
|
||||
* Maybe need to make configurable per-instance.
|
||||
*/
|
||||
private static final long TARGET = 15;
|
||||
private static final int TARGET = 15;
|
||||
private final long _target;
|
||||
|
||||
/**
|
||||
* Quote:
|
||||
* A setting of 100 ms works well across a range of RTTs from 10 ms to 1 second
|
||||
*
|
||||
* Maybe need to make configurable per-instance.
|
||||
*/
|
||||
private static final long INTERVAL = 100;
|
||||
private static final int INTERVAL = 100;
|
||||
private final long _interval;
|
||||
//private static final int MAXPACKET = 512;
|
||||
|
||||
private final String STAT_DROP;
|
||||
@@ -75,14 +75,28 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
|
||||
private static final long BACKLOG_TIME = 2*1000;
|
||||
|
||||
/**
|
||||
* Target 15, interval 100
|
||||
*
|
||||
* @param name for stats
|
||||
*/
|
||||
public CoDelBlockingQueue(I2PAppContext ctx, String name, int capacity) {
|
||||
this(ctx, name, capacity, TARGET, INTERVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target the target max latency (ms)
|
||||
* @param interval how long above target to start dropping (ms)
|
||||
* @param name for stats
|
||||
* @since 0.9.50
|
||||
*/
|
||||
public CoDelBlockingQueue(I2PAppContext ctx, String name, int capacity, int target, int interval) {
|
||||
super(capacity);
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(CoDelBlockingQueue.class);
|
||||
_name = name;
|
||||
_capacity = capacity;
|
||||
_target = target;
|
||||
_interval = interval;
|
||||
STAT_DROP = ("codel." + name + ".drop").intern();
|
||||
STAT_DELAY = ("codel." + name + ".delay").intern();
|
||||
ctx.statManager().createRateStat(STAT_DROP, "queue delay of dropped items", "Router", RATES);
|
||||
@@ -207,13 +221,13 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
|
||||
long sojurn = _now - entry.getEnqueueTime();
|
||||
_context.statManager().addRateData(STAT_DELAY, sojurn);
|
||||
// I2P use isEmpty instead of size() < MAXPACKET
|
||||
if (sojurn < TARGET || isEmpty()) {
|
||||
if (sojurn < _target || isEmpty()) {
|
||||
_first_above_time = 0;
|
||||
} else {
|
||||
if (_first_above_time == 0) {
|
||||
// just went above from below. if we stay above
|
||||
// for at least INTERVAL we'll say it's ok to drop
|
||||
_first_above_time = _now + INTERVAL;
|
||||
// for at least _interval we'll say it's ok to drop
|
||||
_first_above_time = _now + _interval;
|
||||
} else if (_now >= _first_above_time) {
|
||||
ok_to_drop = true;
|
||||
}
|
||||
@@ -270,7 +284,7 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
|
||||
}
|
||||
}
|
||||
} else if (ok_to_drop &&
|
||||
(_now - _drop_next < INTERVAL || _now - _first_above_time >= INTERVAL)) {
|
||||
(_now - _drop_next < _interval || _now - _first_above_time >= _interval)) {
|
||||
// If we get here, then we're not in dropping state. If the sojourn time has been above
|
||||
// target for interval, then we decide whether it's time to enter dropping state.
|
||||
// We do so if we've been either in dropping state recently or above target for a relatively
|
||||
@@ -287,7 +301,7 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
|
||||
_dropping = true;
|
||||
// If we're in a drop cycle, the drop rate that controlled the queue
|
||||
// on the last cycle is a good starting point to control it now.
|
||||
if (_now - _drop_next < INTERVAL)
|
||||
if (_now - _drop_next < _interval)
|
||||
_count = _count > 2 ? _count - 2 : 1;
|
||||
else
|
||||
_count = 1;
|
||||
@@ -313,6 +327,6 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
|
||||
* Caller must synch on this
|
||||
*/
|
||||
private void control_law(long t) {
|
||||
_drop_next = t + (long) (INTERVAL / Math.sqrt(_count));
|
||||
_drop_next = t + (long) (_interval / Math.sqrt(_count));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user