Add UDP announce rate stat
This commit is contained in:
@ -4,7 +4,11 @@
|
||||
s/<Ref id=/<Ref refid=/g
|
||||
- Add interval to stats page
|
||||
- Add stats to I2P stats subsystem
|
||||
- Show announce URLs on stats page
|
||||
- Remove ElGamal support
|
||||
- Remove support for non-compact announce replies
|
||||
- Reduce memory usage
|
||||
- Remove seedless support
|
||||
|
||||
2024-04-07 [0.19.0]
|
||||
- Disable full scrape by default
|
||||
|
@ -22,6 +22,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.I2PSession;
|
||||
@ -51,8 +52,10 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
private final Log _log;
|
||||
private final I2PTunnel _tunnel;
|
||||
private final ZzzOT _zzzot;
|
||||
private final Cleaner _cleaner;
|
||||
private final long sipk0, sipk1;
|
||||
private final Map<Hash, Destination> _destCache;
|
||||
private final AtomicInteger _announces = new AtomicInteger();
|
||||
private volatile boolean _running;
|
||||
|
||||
// The listen port.
|
||||
@ -70,6 +73,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
// keep it short, we should have the leaseset
|
||||
private final long LOOKUP_TIMEOUT = 1000;
|
||||
private final long CLEAN_TIME;
|
||||
private final long STAT_TIME = 2*60*1000;
|
||||
private static final byte[] INVALID = DataHelper.getUTF8("Invalid connection ID");
|
||||
private static final byte[] PROTOCOL = DataHelper.getUTF8("Bad protocol");
|
||||
private static final byte[] SCRAPE = DataHelper.getUTF8("Scrape unsupported");
|
||||
@ -81,6 +85,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
_zzzot = zzzot;
|
||||
CLEAN_TIME = (zzzot.getTorrents().getUDPLifetime() + 60) * 1000;
|
||||
PORT = port;
|
||||
_cleaner = new Cleaner();
|
||||
sipk0 = ctx.random().nextLong();
|
||||
sipk1 = ctx.random().nextLong();
|
||||
// the highest-traffic zzzot is running about 3000 announces/minute,
|
||||
@ -91,6 +96,8 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
public void start() {
|
||||
_running = true;
|
||||
(new I2PAppThread(new Waiter(), "ZzzOT UDP startup", true)).start();
|
||||
long[] r = new long[] { 5*60*1000 };
|
||||
_context.statManager().createRequiredRateStat("plugin.zzzot.announces.udp", "UDP announces per minute", "Plugins", r);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,6 +105,9 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
*/
|
||||
public void stop() {
|
||||
_running = false;
|
||||
_cleaner.cancel();
|
||||
_context.statManager().removeRateStat("plugin.zzzot.announces.udp");
|
||||
_announces.set(0);
|
||||
}
|
||||
|
||||
private class Waiter implements Runnable {
|
||||
@ -112,6 +122,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
I2PSession session = sessions.get(0);
|
||||
session.addMuxedSessionListener(UDPHandler.this, I2PSession.PROTO_DATAGRAM2, PORT);
|
||||
session.addMuxedSessionListener(UDPHandler.this, I2PSession.PROTO_DATAGRAM3, PORT);
|
||||
_cleaner.schedule(STAT_TIME);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("got session");
|
||||
break;
|
||||
@ -154,6 +165,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
public void reportAbuse(I2PSession arg0, int arg1) {}
|
||||
|
||||
public void disconnected(I2PSession arg0) {
|
||||
_cleaner.cancel();
|
||||
}
|
||||
|
||||
public void errorOccurred(I2PSession arg0, String arg1, Throwable arg2) {
|
||||
@ -286,6 +298,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
Torrents torrents = _zzzot.getTorrents();
|
||||
Peers peers = torrents.get(ih);
|
||||
if (peers == null && event != EVENT_STOPPED) {
|
||||
_announces.incrementAndGet();
|
||||
peers = new Peers();
|
||||
Peers p2 = torrents.putIfAbsent(ih, peers);
|
||||
if (p2 != null)
|
||||
@ -433,4 +446,16 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
||||
c = SipHashInline.hash24(sipk0, sipk1, buf);
|
||||
return cid == c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the announce stat and set the announce count to 0
|
||||
*/
|
||||
private class Cleaner extends SimpleTimer2.TimedEvent {
|
||||
public Cleaner() { super(_context.simpleTimer2()); }
|
||||
public void timeReached() {
|
||||
long count = _announces.getAndSet(0);
|
||||
_context.statManager().addRateData("plugin.zzzot.announces.udp", count / (STAT_TIME / (60*1000L)));
|
||||
schedule(STAT_TIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class ZzzOT {
|
||||
void start() {
|
||||
_cleaner.forceReschedule(CLEAN_TIME);
|
||||
long[] r = new long[] { 5*60*1000 };
|
||||
_context.statManager().createRequiredRateStat("plugin.zzzot.announces", "Announces per minute", "Plugins", r);
|
||||
_context.statManager().createRequiredRateStat("plugin.zzzot.announces", "Total announces per minute", "Plugins", r);
|
||||
_context.statManager().createRequiredRateStat("plugin.zzzot.peers", "Number of peers", "Plugins", r);
|
||||
_context.statManager().createRequiredRateStat("plugin.zzzot.torrents", "Number of torrents", "Plugins", r);
|
||||
}
|
||||
|
@ -180,6 +180,20 @@ public class ZzzOTController implements ClientApp {
|
||||
return r.getAvgOrLifetimeAvg();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return announces per minute, 0 if not running or UDP not enabled
|
||||
* @since 0.20.0
|
||||
*/
|
||||
public static double getUDPAnnounceRate() {
|
||||
RateStat rs = I2PAppContext.getGlobalContext().statManager().getRate("plugin.zzzot.announces.udp");
|
||||
if (rs == null)
|
||||
return 0;
|
||||
Rate r = rs.getRate(5*60*1000);
|
||||
if (r == null)
|
||||
return 0;
|
||||
return r.getAvgOrLifetimeAvg();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false if not running
|
||||
* @since 0.20.0
|
||||
|
@ -20,19 +20,31 @@
|
||||
<p id="totals">
|
||||
<b>Torrents:</b> <%=torrents.size()%><br>
|
||||
<b>Peers:</b> <%=torrents.countPeers()%><br>
|
||||
<b>Announce Rate:</b> <%=String.format(java.util.Locale.US, "%.1f", ZzzOTController.getAnnounceRate())%> / minute<br>
|
||||
<%
|
||||
boolean udp = ZzzOTController.isUDPEnabled();
|
||||
if (udp) {
|
||||
%>
|
||||
<b>Total Announce Rate:</b>
|
||||
<%
|
||||
} else {
|
||||
%>
|
||||
<b>Announce Rate:</b>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
<%=String.format(java.util.Locale.US, "%.1f", ZzzOTController.getAnnounceRate())%> / minute<br>
|
||||
<b>Announce Interval:</b> <%=torrents.getInterval() / 60%> minutes<br>
|
||||
<%
|
||||
String host = ZzzOTController.b32();
|
||||
if (host != null) {
|
||||
%><b>Announce URL:</b> <a href="http://<%=host%>/a">http://<%=host%>/a</a><br><%
|
||||
}
|
||||
boolean udp = ZzzOTController.isUDPEnabled();
|
||||
%>
|
||||
<b>UDP Announce Support:</b> <%=udp ? "yes" : "no"%><br>
|
||||
<%
|
||||
if (udp) {
|
||||
%>
|
||||
<b>UDP Announce Rate:</b> <%=String.format(java.util.Locale.US, "%.1f", ZzzOTController.getUDPAnnounceRate())%> / minute<br>
|
||||
<b>UDP Connection Lifetime:</b> <%=torrents.getUDPLifetime() / 60%> minutes<br>
|
||||
<%
|
||||
if (host != null) {
|
||||
|
Reference in New Issue
Block a user