package lbms.plugins.mldht.kad.tasks;
import lbms.plugins.mldht.kad.DHT;
import lbms.plugins.mldht.kad.DHTConstants;
import lbms.plugins.mldht.kad.Key;
import lbms.plugins.mldht.kad.Node;
import lbms.plugins.mldht.kad.RPCServer;
import lbms.plugins.mldht.kad.RPCState;
import lbms.plugins.mldht.kad.tasks.IterativeLookupCandidates.LookupGraphNode;
import lbms.plugins.mldht.kad.utils.AddressUtils;
import lbms.plugins.mldht.kad.DHT.LogLevel;
import java.util.stream.Collectors;
public abstract class IteratingTask extends TargetedTask {
ClosestSet closest;
IterativeLookupCandidates todo;
public IteratingTask(Key target, RPCServer srv, Node node) {
super(target, srv, node);
todo = new IterativeLookupCandidates(target, node.getDHT().getMismatchDetector());
todo.setNonReachableCache(node.getDHT().getUnreachableCache());
todo.setSpamThrottle(node.getDHT().getServerManager().getOutgoingRequestThrottle());
closest = new ClosestSet(target, DHTConstants.MAX_ENTRIES_PER_BUCKET);
}
@Override
public int getTodoCount() {
return (int) todo.allCand().filter(todo.lookupFilter).count();
}
public String closestDebug() {
return this.closest.entries().<String>map(kbe -> {
Key k = kbe.getID();
return k + " " + targetKey.distance(k) + " src:" + todo.nodeForEntry(kbe).sources.size();
}).collect(Collectors.joining("\n"));
}
protected void logClosest() {
Key farthest = closest.tail();
DHT.log(this.toString() + "\n" +
"Task "+ getTaskID() +" done " + counts + " " + closest + "\n" + targetKey + "\n" + closestDebug() + "\n" +
todo.allCand().sorted(todo.comp()).filter(node -> {
return targetKey.threeWayDistance(node.toKbe().getID(), farthest) <= 0;
}).<String>map(node -> {
return String.format("%s %s %s %s%s%s%s%s fail:%d src:%d call:%d rsp:%d acc:%d %s",
node.toKbe().getID(),
targetKey.distance(node.toKbe().getID()),
AddressUtils.toString(node.toKbe().getAddress()),
node.toKbe().hasSecureID() ? "🔒" : " ",
node.root ? "🌲" : " ",
node.tainted ? "!" : " ",
node.throttled ? "⏳" : " ",
node.unreachable ? "⛔" : " ",
-node.previouslyFailedCount,
node.sources.size(),
node.calls.size(),
node.calls.stream().filter(c -> c.state() == RPCState.RESPONDED).count(),
node.acceptedResponse ? 1 : 0,
node.sources.stream().map(LookupGraphNode::toKbe).collect(Collectors.toList())
);
}).collect(Collectors.joining("\n"))
, LogLevel.Verbose);
}
}