|
|
|
@ -79,7 +79,7 @@ import de.anomic.server.logging.serverLog;
|
|
|
|
|
public class yacyCore {
|
|
|
|
|
|
|
|
|
|
// statics
|
|
|
|
|
public static ThreadGroup publishThreadGroup = new ThreadGroup("publishThreadGroup");
|
|
|
|
|
public static final ThreadGroup publishThreadGroup = new ThreadGroup("publishThreadGroup");
|
|
|
|
|
public static yacySeedDB seedDB = null;
|
|
|
|
|
public static yacyNewsPool newsPool = null;
|
|
|
|
|
public static final HashMap seedUploadMethods = new HashMap();
|
|
|
|
@ -92,12 +92,12 @@ public class yacyCore {
|
|
|
|
|
public static File yacyDBPath;
|
|
|
|
|
public static final Map amIAccessibleDB = Collections.synchronizedMap(new HashMap()); // Holds PeerHash / yacyAccessible Relations
|
|
|
|
|
// constants for PeerPing behaviour
|
|
|
|
|
private static final int peerPingInitial = 10;
|
|
|
|
|
private static final int peerPingMaxRunning = 3;
|
|
|
|
|
private static final int peerPingMinRunning = 1;
|
|
|
|
|
private static final int peerPingMinDBSize = 5;
|
|
|
|
|
private static final int peerPingMinAccessibleToForceSenior = 3;
|
|
|
|
|
private static final long peerPingMaxDBAge = 15 * 60 * 1000; // in milliseconds
|
|
|
|
|
private static final int PING_INITIAL = 10;
|
|
|
|
|
private static final int PING_MAX_RUNNING = 3;
|
|
|
|
|
private static final int PING_MIN_RUNNING = 1;
|
|
|
|
|
private static final int PING_MIN_DBSIZE = 5;
|
|
|
|
|
private static final int PING_MIN_PEERSEEN = 1; // min. accessible to force senior
|
|
|
|
|
private static final long PING_MAX_DBAGE = 15 * 60 * 1000; // in milliseconds
|
|
|
|
|
|
|
|
|
|
// public static yacyShare shareManager = null;
|
|
|
|
|
// public static boolean terminate = false;
|
|
|
|
@ -186,7 +186,7 @@ public class yacyCore {
|
|
|
|
|
lastOnlineTime = System.currentTimeMillis();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean online() {
|
|
|
|
|
public final boolean online() {
|
|
|
|
|
onlineMode = Integer.parseInt(switchboard.getConfig("onlineMode", "1"));
|
|
|
|
|
return ((onlineMode == 2) || ((System.currentTimeMillis() - lastOnlineTime) < 10000));
|
|
|
|
|
}
|
|
|
|
@ -200,13 +200,13 @@ public class yacyCore {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void loadSeeds() {
|
|
|
|
|
public final void loadSeeds() {
|
|
|
|
|
//new Thread(new vprobe()).start();
|
|
|
|
|
peerActions.loadSeedLists(); // start to bootstrap the network here
|
|
|
|
|
publishSeedList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void publishSeedList() {
|
|
|
|
|
public final void publishSeedList() {
|
|
|
|
|
log.logFine("yacyCore.publishSeedList: Triggered Seed Publish");
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -218,8 +218,7 @@ public class yacyCore {
|
|
|
|
|
yacyCore.log.logDebug("***DEBUG publishSeedList: I can reach myself");
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(this.lastSeedUpload_myIP.equals(seedDB.mySeed.get(yacySeed.IP, "127.0.0.1"))) &&
|
|
|
|
|
if ((this.lastSeedUpload_myIP.equals(seedDB.mySeed.get(yacySeed.IP, "127.0.0.1"))) &&
|
|
|
|
|
(this.lastSeedUpload_seedDBSize == seedDB.sizeConnected()) &&
|
|
|
|
|
(canReachMyself()) &&
|
|
|
|
|
(System.currentTimeMillis() - this.lastSeedUpload_timeStamp < 1000 * 60 * 60 * 24) &&
|
|
|
|
@ -238,22 +237,26 @@ public class yacyCore {
|
|
|
|
|
((seedUploadMethod.equals("")) && (this.switchboard.getConfig("seedFilePath", "").length() > 0))
|
|
|
|
|
) {
|
|
|
|
|
if (seedUploadMethod.equals("")) {
|
|
|
|
|
if (this.switchboard.getConfig("seedFTPPassword", "").length() > 0)
|
|
|
|
|
if (this.switchboard.getConfig("seedFTPPassword", "").length() > 0) {
|
|
|
|
|
this.switchboard.setConfig("seedUploadMethod", "Ftp");
|
|
|
|
|
if (this.switchboard.getConfig("seedFilePath", "").length() > 0)
|
|
|
|
|
}
|
|
|
|
|
if (this.switchboard.getConfig("seedFilePath", "").length() > 0) {
|
|
|
|
|
this.switchboard.setConfig("seedUploadMethod", "File");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// we want to be a principal...
|
|
|
|
|
saveSeedList();
|
|
|
|
|
} else {
|
|
|
|
|
if (seedUploadMethod.equals("")) this.switchboard.setConfig("seedUploadMethod","none");
|
|
|
|
|
if (seedUploadMethod.equals("")) {
|
|
|
|
|
this.switchboard.setConfig("seedUploadMethod", "none");
|
|
|
|
|
}
|
|
|
|
|
log.logFine("yacyCore.publishSeedList: No uploading method configured");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void peerPing() {
|
|
|
|
|
if (!online()) return;
|
|
|
|
|
public final void peerPing() {
|
|
|
|
|
if (!online()) { return; }
|
|
|
|
|
if ((switchboard.isRobinsonMode()) && (switchboard.getConfig("cluster.mode", "").equals("privatepeer"))) {
|
|
|
|
|
// in case this peer is a privat peer we omit the peer ping
|
|
|
|
|
// all other robinson peer types do a peer ping:
|
|
|
|
@ -267,15 +270,15 @@ public class yacyCore {
|
|
|
|
|
peerActions.updateMySeed();
|
|
|
|
|
|
|
|
|
|
// publish own seed to other peer, this can every peer, but makes only sense for senior peers
|
|
|
|
|
final int oldSize = seedDB.sizeConnected();
|
|
|
|
|
if (oldSize == 0) {
|
|
|
|
|
if (seedDB.sizeConnected() == 0) {
|
|
|
|
|
// reload the seed lists
|
|
|
|
|
peerActions.loadSeedLists();
|
|
|
|
|
log.logInfo("re-initialized seed list. received " + seedDB.sizeConnected() + " new peer(s)");
|
|
|
|
|
}
|
|
|
|
|
final int newSeeds = publishMySeed(false);
|
|
|
|
|
if (newSeeds > 0) log.logInfo("received " + newSeeds + " new peer(s), know a total of " +
|
|
|
|
|
seedDB.sizeConnected() + " different peers");
|
|
|
|
|
if (newSeeds > 0) {
|
|
|
|
|
log.logInfo("received " + newSeeds + " new peer(s), know a total of " + seedDB.sizeConnected() + " different peers");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean canReachMyself() { // TODO: check if this method is necessary - depending on the used router it will not work
|
|
|
|
@ -293,13 +296,14 @@ public class yacyCore {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected class publishThread extends Thread {
|
|
|
|
|
public int added;
|
|
|
|
|
public yacySeed seed;
|
|
|
|
|
public Exception error;
|
|
|
|
|
private int added;
|
|
|
|
|
private yacySeed seed;
|
|
|
|
|
private Exception error;
|
|
|
|
|
private final serverSemaphore sync;
|
|
|
|
|
private final List syncList;
|
|
|
|
|
|
|
|
|
|
public publishThread(ThreadGroup tg, yacySeed seed, serverSemaphore sync, List syncList) throws InterruptedException {
|
|
|
|
|
public publishThread(ThreadGroup tg, yacySeed seed,
|
|
|
|
|
serverSemaphore sync, List syncList) throws InterruptedException {
|
|
|
|
|
super(tg, "PublishSeed_" + seed.getName());
|
|
|
|
|
|
|
|
|
|
this.sync = sync;
|
|
|
|
@ -311,7 +315,7 @@ public class yacyCore {
|
|
|
|
|
this.error = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void run() {
|
|
|
|
|
public final void run() {
|
|
|
|
|
try {
|
|
|
|
|
this.added = yacyClient.publishMySeed(seed.getClusterAddress(), seed.hash);
|
|
|
|
|
if (this.added < 0) {
|
|
|
|
@ -362,7 +366,7 @@ public class yacyCore {
|
|
|
|
|
|
|
|
|
|
// getting a list of peers to contact
|
|
|
|
|
if (seedDB.mySeed.get(yacySeed.PEERTYPE, yacySeed.PEERTYPE_VIRGIN).equals(yacySeed.PEERTYPE_VIRGIN)) {
|
|
|
|
|
if (attempts > peerPingInitial) { attempts = peerPingInitial; }
|
|
|
|
|
if (attempts > PING_INITIAL) { attempts = PING_INITIAL; }
|
|
|
|
|
Map ch = plasmaSwitchboard.getSwitchboard().clusterhashes;
|
|
|
|
|
seeds = seedDB.seedsByAge(true, attempts - ((ch == null) ? 0 : ch.size())); // best for fast connection
|
|
|
|
|
// add also all peers from cluster if this is a public robinson cluster
|
|
|
|
@ -384,12 +388,12 @@ public class yacyCore {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
int diff = peerPingMinDBSize - amIAccessibleDB.size();
|
|
|
|
|
if (diff > peerPingMinRunning) {
|
|
|
|
|
diff = Math.min(diff, peerPingMaxRunning);
|
|
|
|
|
int diff = PING_MIN_DBSIZE - amIAccessibleDB.size();
|
|
|
|
|
if (diff > PING_MIN_RUNNING) {
|
|
|
|
|
diff = Math.min(diff, PING_MAX_RUNNING);
|
|
|
|
|
if (attempts > diff) { attempts = diff; }
|
|
|
|
|
} else {
|
|
|
|
|
if (attempts > peerPingMinRunning) { attempts = peerPingMinRunning; }
|
|
|
|
|
if (attempts > PING_MIN_RUNNING) { attempts = PING_MIN_RUNNING; }
|
|
|
|
|
}
|
|
|
|
|
seeds = seedDB.seedsByAge(false, attempts); // best for seed list maintenance/cleaning
|
|
|
|
|
}
|
|
|
|
@ -439,7 +443,7 @@ public class yacyCore {
|
|
|
|
|
// going through the peer list and starting a new publisher thread for each peer
|
|
|
|
|
for (int i = 0; i < attempts; i++) {
|
|
|
|
|
seed = (yacySeed) seedList.remove(0);
|
|
|
|
|
if (seed == null) continue;
|
|
|
|
|
if (seed == null) { continue; }
|
|
|
|
|
|
|
|
|
|
final String address = seed.getClusterAddress();
|
|
|
|
|
log.logFine("HELLO #" + i + " to peer '" + seed.get(yacySeed.NAME, "") + "' at " + address); // debug
|
|
|
|
@ -482,7 +486,7 @@ public class yacyCore {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Nobody contacted yet, try again until peerPingInitial attempts are through
|
|
|
|
|
while ((newSeeds < 0) && (contactedSeedCount < peerPingInitial) && (!seedList.isEmpty())) {
|
|
|
|
|
while ((newSeeds < 0) && (contactedSeedCount < PING_INITIAL) && (!seedList.isEmpty())) {
|
|
|
|
|
seed = (yacySeed) seedList.remove(0);
|
|
|
|
|
if (seed != null) {
|
|
|
|
|
String address = seed.getPublicAddress();
|
|
|
|
@ -511,7 +515,7 @@ public class yacyCore {
|
|
|
|
|
|
|
|
|
|
int accessible = 0;
|
|
|
|
|
int notaccessible = 0;
|
|
|
|
|
final long cutofftime = System.currentTimeMillis() - peerPingMaxDBAge;
|
|
|
|
|
final long cutofftime = System.currentTimeMillis() - PING_MAX_DBAGE;
|
|
|
|
|
final int dbSize;
|
|
|
|
|
synchronized (amIAccessibleDB) {
|
|
|
|
|
dbSize = amIAccessibleDB.size();
|
|
|
|
@ -521,19 +525,22 @@ public class yacyCore {
|
|
|
|
|
if (ya.lastUpdated < cutofftime) {
|
|
|
|
|
ai.remove();
|
|
|
|
|
} else {
|
|
|
|
|
if (ya.IWasAccessed) { accessible++; }
|
|
|
|
|
else { notaccessible++; }
|
|
|
|
|
if (ya.IWasAccessed) {
|
|
|
|
|
accessible++;
|
|
|
|
|
} else {
|
|
|
|
|
notaccessible++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
log.logFine("DBSize before -> after Cleanup: " + dbSize + " -> " + amIAccessibleDB.size());
|
|
|
|
|
}
|
|
|
|
|
log.logInfo("PeerPing: I am accessible for " + accessible +
|
|
|
|
|
" peer(s), not accessible for " + notaccessible + " peer(s).");
|
|
|
|
|
|
|
|
|
|
if ((accessible + notaccessible) > 0) {
|
|
|
|
|
final String newPeerType;
|
|
|
|
|
// At least one other Peer told us our type
|
|
|
|
|
if ((accessible >= peerPingMinAccessibleToForceSenior) ||
|
|
|
|
|
if ((accessible >= PING_MIN_PEERSEEN) ||
|
|
|
|
|
(accessible >= notaccessible)) {
|
|
|
|
|
// We can be reached from a majority of other Peers
|
|
|
|
|
if (yacyCore.seedDB.mySeed.isPrincipal()) {
|
|
|
|
@ -623,8 +630,7 @@ public class yacyCore {
|
|
|
|
|
|
|
|
|
|
log.logInfo("publish: Shutdown off all remaining publishing thread finished.");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ee) {
|
|
|
|
|
} catch (Exception ee) {
|
|
|
|
|
log.logWarning("publish: Unexpected error while trying to shutdown all remaining publishing threads.", e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -672,7 +678,8 @@ public class yacyCore {
|
|
|
|
|
final String[] uploaderClasses = uploadersDir.list(new FilenameFilter() {
|
|
|
|
|
public boolean accept(File dir, String name) {
|
|
|
|
|
return name.startsWith("yacySeedUpload") && name.endsWith(".class");
|
|
|
|
|
}});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final String javaClassPath = System.getProperty("java.class.path");
|
|
|
|
|
|
|
|
|
@ -694,10 +701,10 @@ public class yacyCore {
|
|
|
|
|
}
|
|
|
|
|
availableUploaders.put(className.substring("yacySeedUpload".length()), fullClassName);
|
|
|
|
|
} catch (Exception e) { /* we can ignore this for the moment */
|
|
|
|
|
} catch (Error e) { /* we can ignore this for the moment */ }
|
|
|
|
|
} catch (Error e) { /* we can ignore this for the moment */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
synchronized (yacyCore.seedUploadMethods) {
|
|
|
|
|
yacyCore.seedUploadMethods.clear();
|
|
|
|
@ -707,21 +714,21 @@ public class yacyCore {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean changeSeedUploadMethod(String method) {
|
|
|
|
|
if (method == null || method.length() == 0) return false;
|
|
|
|
|
if (method == null || method.length() == 0) { return false; }
|
|
|
|
|
|
|
|
|
|
if (method.equalsIgnoreCase("none")) return true;
|
|
|
|
|
if (method.equalsIgnoreCase("none")) { return true; }
|
|
|
|
|
|
|
|
|
|
synchronized (yacyCore.seedUploadMethods) {
|
|
|
|
|
return yacyCore.seedUploadMethods.containsKey(method);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String saveSeedList() {
|
|
|
|
|
public final String saveSeedList() {
|
|
|
|
|
// return an error if this is not successful, and NULL if everything is fine
|
|
|
|
|
return saveSeedList(this.switchboard);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String saveSeedList(serverSwitch sb) {
|
|
|
|
|
public final String saveSeedList(serverSwitch sb) {
|
|
|
|
|
try {
|
|
|
|
|
// return an error if this is not successful, and NULL if everything is fine
|
|
|
|
|
String logt;
|
|
|
|
@ -738,13 +745,16 @@ public class yacyCore {
|
|
|
|
|
|
|
|
|
|
// for backward compatiblity ....
|
|
|
|
|
if (seedUploadMethod.equalsIgnoreCase("Ftp") ||
|
|
|
|
|
(seedUploadMethod.equals("") && sb.getConfig("seedFTPPassword", "").length() > 0)
|
|
|
|
|
) {
|
|
|
|
|
(seedUploadMethod.equals("") &&
|
|
|
|
|
sb.getConfig("seedFTPPassword", "").length() > 0)) {
|
|
|
|
|
|
|
|
|
|
seedUploadMethod = "Ftp";
|
|
|
|
|
sb.setConfig("seedUploadMethod", seedUploadMethod);
|
|
|
|
|
|
|
|
|
|
} else if (seedUploadMethod.equalsIgnoreCase("File") ||
|
|
|
|
|
(seedUploadMethod.equals("") && sb.getConfig("seedFilePath", "").length() > 0)
|
|
|
|
|
) {
|
|
|
|
|
(seedUploadMethod.equals("") &&
|
|
|
|
|
sb.getConfig("seedFilePath", "").length() > 0)) {
|
|
|
|
|
|
|
|
|
|
seedUploadMethod = "File";
|
|
|
|
|
sb.setConfig("seedUploadMethod", seedUploadMethod);
|
|
|
|
|
}
|
|
|
|
|