Iterate through the swarms in order of last pinged, get hosts which have not been pinged recently, also in chronological order

This commit is contained in:
Zlatin Balevsky
2020-04-29 06:07:22 +01:00
parent eec9bab081
commit 2001419f1a
2 changed files with 51 additions and 2 deletions

View File

@ -34,6 +34,11 @@ class Swarm {
*/
private long lastQueryTime
/**
* Last time a batch of hosts was pinged
*/
private long lastPingTime
Swarm(InfoHash infoHash) {
this.infoHash = infoHash
}
@ -119,13 +124,21 @@ class Swarm {
negative.add(h.persona)
}
synchronized List<Host> getBatchToPing(int max) {
/**
* @param max number of hosts to give back
* @param now what time is it now
* @param cutoff only consider hosts which have been pinged before this time
* @return hosts to be pinged
*/
synchronized List<Host> getBatchToPing(int max, long now, long cutOff) {
List<Host> rv = new ArrayList<>()
rv.addAll(unknown.values())
rv.addAll(seeds.values())
rv.addAll(leeches.values())
rv.removeAll(inFlight.values())
rv.removeAll { it.lastPinged >= cutOff }
Collections.sort(rv, {l, r ->
Long.compare(l.lastPinged, r.lastPinged)
} as Comparator<Host>)
@ -133,15 +146,20 @@ class Swarm {
if (rv.size() > max)
rv = rv[0..(max-1)]
final long now = System.currentTimeMillis()
rv.each {
it.lastPinged = now
inFlight.put(it.persona, it)
}
if (!rv.isEmpty())
lastPingTime = now
rv
}
synchronized long getLastPingTime() {
lastPingTime
}
public Info info() {
List<String> seeders = seeds.keySet().collect { it.getHumanReadableName() }
List<String> leechers = leeches.keySet().collect { it.getHumanReadableName() }

View File

@ -73,6 +73,23 @@ class SwarmManager {
if (it.shouldQuery(queryCutoff, now))
query(it)
}
List<Swarm> swarmList = new ArrayList<>(swarms.values())
Collections.sort(swarmList,{Swarm x, Swarm y ->
Long.compare(x.getLastPingTime(), y.getLastPingTime())
} as Comparator<Swarm>)
List<HostAndIH> toPing = new ArrayList<>()
final int amount = trackerProperties.getSwarmParameters().getPingParallel()
final int pingCutoff = now - trackerProperties.getSwarmParameters().getPingInterval() * 60 * 1000L
for(int i = 0; i < swarmList.size() && toPing.size() < amount; i++) {
Swarm s = swarmList.get(i)
List<Host> hostsFromSwarm = s.getBatchToPing(amount - toPing.size(), now, pingCutoff)
hostsFromSwarm.collect(toPing, { host -> new HostAndIH(host, s.getInfoHash())})
}
log.info("will ping $toPing")
}
private void query(Swarm swarm) {
@ -114,4 +131,18 @@ class SwarmManager {
Swarm.Info info(InfoHash infoHash) {
swarms.get(infoHash)?.info()
}
private static class HostAndIH {
private final Host host
private final InfoHash infoHash
HostAndIH(Host host, InfoHash infoHash) {
this.host = host
this.infoHash = infoHash
}
@Override
public String toString() {
"$host:$infoHash"
}
}
}