add a max failuires parameter when deciding whether to expire a host. Report the number of negative hosts in the info rpc
This commit is contained in:
@@ -10,18 +10,19 @@ class Host {
|
|||||||
final Persona persona
|
final Persona persona
|
||||||
long lastPinged
|
long lastPinged
|
||||||
long lastResponded
|
long lastResponded
|
||||||
|
int failures
|
||||||
volatile String xHave
|
volatile String xHave
|
||||||
|
|
||||||
Host(Persona persona) {
|
Host(Persona persona) {
|
||||||
this.persona = persona
|
this.persona = persona
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isExpired(long cutoff) {
|
boolean isExpired(long cutoff, int maxFailures) {
|
||||||
lastPinged > lastResponded && lastResponded <= cutoff
|
lastPinged > lastResponded && lastResponded <= cutoff && failures >= maxFailures
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
"Host:[${persona.getHumanReadableName()} lastPinged:$lastPinged lastResponded:$lastResponded xHave:$xHave]"
|
"Host:[${persona.getHumanReadableName()} lastPinged:$lastPinged lastResponded:$lastResponded failures:$failures xHave:$xHave]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -46,17 +46,17 @@ class Swarm {
|
|||||||
/**
|
/**
|
||||||
* @param cutoff expire hosts older than this
|
* @param cutoff expire hosts older than this
|
||||||
*/
|
*/
|
||||||
synchronized void expire(long cutoff) {
|
synchronized void expire(long cutoff, int maxFailures) {
|
||||||
doExpire(cutoff, seeds)
|
doExpire(cutoff, maxFailures, seeds)
|
||||||
doExpire(cutoff, leeches)
|
doExpire(cutoff, maxFailures, leeches)
|
||||||
doExpire(cutoff, unknown)
|
doExpire(cutoff, maxFailures, unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doExpire(long cutoff, Map<Persona,Host> map) {
|
private static void doExpire(long cutoff, int maxFailures, Map<Persona,Host> map) {
|
||||||
for (Iterator<Persona> iter = map.keySet().iterator(); iter.hasNext();) {
|
for (Iterator<Persona> iter = map.keySet().iterator(); iter.hasNext();) {
|
||||||
Persona p = iter.next()
|
Persona p = iter.next()
|
||||||
Host h = map.get(p)
|
Host h = map.get(p)
|
||||||
if (h.isExpired(cutoff))
|
if (h.isExpired(cutoff, maxFailures))
|
||||||
iter.remove()
|
iter.remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,8 @@ class Swarm {
|
|||||||
if (responder != h)
|
if (responder != h)
|
||||||
log.warning("received a response mismatch from host $responder vs $h")
|
log.warning("received a response mismatch from host $responder vs $h")
|
||||||
|
|
||||||
responder.lastResponded = System.currentTimeMillis()
|
responder.lastResponded = System.currentTimeMillis()
|
||||||
|
responder.failures = 0
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case 200: addSeed(responder); break
|
case 200: addSeed(responder); break
|
||||||
case 206 : addLeech(responder); break;
|
case 206 : addLeech(responder); break;
|
||||||
@@ -103,6 +104,7 @@ class Swarm {
|
|||||||
Host h = inFlight.remove(failed.persona)
|
Host h = inFlight.remove(failed.persona)
|
||||||
if (h != failed)
|
if (h != failed)
|
||||||
log.warning("failed a host that wasn't in flight $failed vs $h")
|
log.warning("failed a host that wasn't in flight $failed vs $h")
|
||||||
|
h.failures++
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSeed(Host h) {
|
private void addSeed(Host h) {
|
||||||
@@ -163,17 +165,18 @@ class Swarm {
|
|||||||
public Info info() {
|
public Info info() {
|
||||||
List<String> seeders = seeds.keySet().collect { it.getHumanReadableName() }
|
List<String> seeders = seeds.keySet().collect { it.getHumanReadableName() }
|
||||||
List<String> leechers = leeches.keySet().collect { it.getHumanReadableName() }
|
List<String> leechers = leeches.keySet().collect { it.getHumanReadableName() }
|
||||||
return new Info(seeders, leechers, unknown.size())
|
return new Info(seeders, leechers, unknown.size(), negative.size())
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Info {
|
public static class Info {
|
||||||
final List<String> seeders, leechers
|
final List<String> seeders, leechers
|
||||||
final int unknown
|
final int unknown, negative
|
||||||
|
|
||||||
Info(List<String> seeders, List<String> leechers, int unknown) {
|
Info(List<String> seeders, List<String> leechers, int unknown, int negative) {
|
||||||
this.seeders = seeders
|
this.seeders = seeders
|
||||||
this.leechers = leechers
|
this.leechers = leechers
|
||||||
this.unknown = unknown
|
this.unknown = unknown
|
||||||
|
this.negative = negative
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -68,7 +68,8 @@ class SwarmManager {
|
|||||||
private void trackSwarms() {
|
private void trackSwarms() {
|
||||||
final long now = System.currentTimeMillis()
|
final long now = System.currentTimeMillis()
|
||||||
final long expiryCutoff = now - trackerProperties.getSwarmParameters().getExpiry() * 60 * 1000L
|
final long expiryCutoff = now - trackerProperties.getSwarmParameters().getExpiry() * 60 * 1000L
|
||||||
swarms.values().each { it.expire(expiryCutoff) }
|
final int maxFailures = trackerProperties.getSwarmParameters().getMaxFailures()
|
||||||
|
swarms.values().each { it.expire(expiryCutoff, maxFailures) }
|
||||||
final long queryCutoff = now - trackerProperties.getSwarmParameters().getQueryInterval() * 60 * 60 * 1000L
|
final long queryCutoff = now - trackerProperties.getSwarmParameters().getQueryInterval() * 60 * 60 * 1000L
|
||||||
swarms.values().each {
|
swarms.values().each {
|
||||||
if (it.shouldQuery(queryCutoff, now))
|
if (it.shouldQuery(queryCutoff, now))
|
||||||
@@ -136,6 +137,7 @@ class SwarmManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void fail(HostAndIH target) {
|
void fail(HostAndIH target) {
|
||||||
|
log.info("failing $target")
|
||||||
swarms.get(target.infoHash)?.fail(target.host)
|
swarms.get(target.infoHash)?.fail(target.host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,5 +27,7 @@ class TrackerProperties {
|
|||||||
int expiry = 60
|
int expiry = 60
|
||||||
/** how long to wait for a host to respond to a ping, in seconds */
|
/** how long to wait for a host to respond to a ping, in seconds */
|
||||||
int pingTimeout = 20
|
int pingTimeout = 20
|
||||||
|
/** Do not expire a host until it has failed this many times */
|
||||||
|
int maxFailures = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user