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