From 10d9eb70c8c917b34a9c24713836eb6cb78260e9 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sat, 1 Sep 2012 16:30:12 +0000
Subject: [PATCH] CoDel:   - Add logging of drops   - Set drop stat to delay of
 dropped item   - Add no-drop priority

---
 .../i2p/router/util/CoDelBlockingQueue.java    | 13 +++++++++++--
 .../util/CoDelPriorityBlockingQueue.java       | 18 ++++++++++++++++--
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/router/java/src/net/i2p/router/util/CoDelBlockingQueue.java b/router/java/src/net/i2p/router/util/CoDelBlockingQueue.java
index e67387a43f..92da097d31 100644
--- a/router/java/src/net/i2p/router/util/CoDelBlockingQueue.java
+++ b/router/java/src/net/i2p/router/util/CoDelBlockingQueue.java
@@ -5,6 +5,7 @@ import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 import net.i2p.I2PAppContext;
+import net.i2p.util.Log;
 
 /**
  *  CoDel implementation of Active Queue Management.
@@ -24,6 +25,8 @@ import net.i2p.I2PAppContext;
 public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<E> {
 
     private final I2PAppContext _context;
+    private final Log _log;
+    private final String _name;
 
     // following 4 are state variables defined by sample code, locked by this
     /** Time when we'll declare we're above target (0 if below) */
@@ -66,9 +69,11 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
     public CoDelBlockingQueue(I2PAppContext ctx, String name, int capacity) {
         super(capacity);
         _context = ctx;
+        _log = ctx.logManager().getLog(CoDelBlockingQueue.class);
+        _name = name;
         STAT_DROP = "codel." + name + ".drop";
         STAT_DELAY = "codel." + name + ".delay";
-        ctx.statManager().createRequiredRateStat(STAT_DROP, "AQM drop events", "Router", RATES);
+        ctx.statManager().createRequiredRateStat(STAT_DROP, "queue delay of dropped items", "Router", RATES);
         ctx.statManager().createRequiredRateStat(STAT_DELAY, "average queue delay", "Router", RATES);
     }
 
@@ -254,7 +259,11 @@ public class CoDelBlockingQueue<E extends CDQEntry> extends LinkedBlockingQueue<
     }
 
     private void drop(E entry) {
-        _context.statManager().addRateData(STAT_DROP, 1);
+        long delay = _context.clock().now() - entry.getEnqueueTime();
+        _context.statManager().addRateData(STAT_DROP, delay);
+        if (_log.shouldLog(Log.WARN))
+            _log.warn(_name + " dropped item with delay " + delay + ", " +
+                      size() + " remaining in queue: " + entry);
         entry.drop();
     }
 
diff --git a/router/java/src/net/i2p/router/util/CoDelPriorityBlockingQueue.java b/router/java/src/net/i2p/router/util/CoDelPriorityBlockingQueue.java
index 168e867d0d..372e44664f 100644
--- a/router/java/src/net/i2p/router/util/CoDelPriorityBlockingQueue.java
+++ b/router/java/src/net/i2p/router/util/CoDelPriorityBlockingQueue.java
@@ -7,6 +7,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 import net.i2p.I2PAppContext;
+import net.i2p.util.Log;
 
 /**
  *  CoDel implementation of Active Queue Management.
@@ -26,6 +27,8 @@ import net.i2p.I2PAppContext;
 public class CoDelPriorityBlockingQueue<E extends CDPQEntry> extends PriorityBlockingQueue<E> {
 
     private final I2PAppContext _context;
+    private final Log _log;
+    private final String _name;
     private final AtomicLong _seqNum = new AtomicLong();
 
     // following 4 are state variables defined by sample code, locked by this
@@ -65,6 +68,8 @@ public class CoDelPriorityBlockingQueue<E extends CDPQEntry> extends PriorityBlo
     private final String STAT_DELAY;
     private static final long[] RATES = {5*60*1000};
     private static final int[] PRIORITIES = {100, 200, 300, 400, 500};
+    /** if priority is >= this, never drop */
+    public static final int DONT_DROP_PRIORITY = 1000;
 
     /**
      *  @param name for stats
@@ -72,10 +77,12 @@ public class CoDelPriorityBlockingQueue<E extends CDPQEntry> extends PriorityBlo
     public CoDelPriorityBlockingQueue(I2PAppContext ctx, String name, int initialCapacity) {
         super(initialCapacity, new PriorityComparator());
         _context = ctx;
+        _log = ctx.logManager().getLog(CoDelPriorityBlockingQueue.class);
+        _name = name;
         STAT_DROP = "codel." + name + ".drop.";
         STAT_DELAY = "codel." + name + ".delay";
         for (int i = 0; i < PRIORITIES.length; i++) {
-            ctx.statManager().createRequiredRateStat(STAT_DROP + PRIORITIES[i], "AQM drop events by priority", "Router", RATES);
+            ctx.statManager().createRequiredRateStat(STAT_DROP + PRIORITIES[i], "queue delay of dropped items by priority", "Router", RATES);
         }
         ctx.statManager().createRequiredRateStat(STAT_DELAY, "average queue delay", "Router", RATES);
     }
@@ -237,6 +244,7 @@ public class CoDelPriorityBlockingQueue<E extends CDPQEntry> extends PriorityBlo
                     }
                 }
             } else if (ok_to_drop &&
+                       rv.getPriority() < DONT_DROP_PRIORITY &&
                        (_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.
@@ -266,7 +274,13 @@ public class CoDelPriorityBlockingQueue<E extends CDPQEntry> extends PriorityBlo
     }
 
     private void drop(E entry) {
-        _context.statManager().addRateData(STAT_DROP + entry.getPriority(), 1);
+        long delay = _context.clock().now() - entry.getEnqueueTime();
+        _context.statManager().addRateData(STAT_DROP + entry.getPriority(), delay);
+        if (_log.shouldLog(Log.WARN))
+            _log.warn(_name + " dropped item with delay " + delay + ", priority " +
+                      entry.getPriority() + ", seq " +
+                      entry.getSeqNum() + ", " +
+                      size() + " remaining in queue: " + entry);
         entry.drop();
     }
 
-- 
GitLab