lots of bitchin' oOo patches (woot, thanks oOo!), plus some cleanup
* apply oOo's patch for beautifying the new console w/ links to a shitlisted peer's netDb entry * apply oOo's patch to clean up the peer shitlist count more aggressively * apply oOo's patch to allow removing lines via /configadvanced.jsp * apply oOo's patch to clean up the memory usage display * apply oOo's patch to include log messages on /logs.jsp most recent first, rather than last * get rid of the netDb key shitlist (its a bad idea, better solution coming soon)
This commit is contained in:
@ -4,6 +4,8 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Handler to deal with form submissions from the advanced config form and act
|
||||
@ -41,6 +43,7 @@ public class ConfigAdvancedHandler extends FormHandler {
|
||||
*
|
||||
*/
|
||||
private void saveChanges() {
|
||||
HashSet unsetKeys = new HashSet(_context.router().getConfigMap().keySet());
|
||||
if (_config != null) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(_config.getBytes())));
|
||||
String line = null;
|
||||
@ -52,12 +55,19 @@ public class ConfigAdvancedHandler extends FormHandler {
|
||||
String key = line.substring(0, eq).trim();
|
||||
String val = line.substring(eq + 1).trim();
|
||||
_context.router().setConfigSetting(key, val);
|
||||
unsetKeys.remove(key);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
addFormError("Error updating the configuration (IOERROR) - please see the error logs");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Iterator cleaner = unsetKeys.iterator();
|
||||
while (cleaner.hasNext()) {
|
||||
String unsetKey = (String)cleaner.next();
|
||||
_context.router().removeConfigSetting(unsetKey);
|
||||
}
|
||||
|
||||
boolean saved = _context.router().saveConfig();
|
||||
if (saved)
|
||||
addFormNotice("Configuration saved successfully");
|
||||
|
@ -29,8 +29,8 @@ public class LogsHelper {
|
||||
StringBuffer buf = new StringBuffer(16*1024);
|
||||
buf.append("<h2>Most recent console messages:</h2><ul>");
|
||||
buf.append("<code>\n");
|
||||
for (int i = 0; i < msgs.size(); i++) {
|
||||
String msg = (String)msgs.get(i);
|
||||
for (int i = msgs.size(); i > 0; i--) {
|
||||
String msg = (String)msgs.get(i - 1);
|
||||
buf.append("<li>");
|
||||
buf.append(msg);
|
||||
buf.append("</li>\n");
|
||||
|
@ -71,9 +71,10 @@ public class SummaryHelper {
|
||||
*
|
||||
*/
|
||||
public String getMemory() {
|
||||
DecimalFormat integerFormatter = new DecimalFormat("###,###,##0");
|
||||
long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024;
|
||||
long usedPc = 100 - ((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory());
|
||||
return used + "KB (" + usedPc + "%)";
|
||||
return integerFormatter.format(used) + "KB (" + usedPc + "%)";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,7 +23,7 @@
|
||||
<i><jsp:getProperty name="formhandler" property="notices" /></i>
|
||||
|
||||
<form action="configadvanced.jsp" method="POST">
|
||||
<textarea rows="20" cols="80" name="config"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br />
|
||||
<textarea rows="20" cols="100" name="config"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br />
|
||||
<input type="submit" name="shouldsave" value="Apply" /> <input type="reset" value="Cancel" /> <br />
|
||||
<b>Force restart:</b> <input type="checkbox" name="restart" value="force" /> <i>(specify this
|
||||
if the changes made above require the router to reset itself - e.g. you are updating TCP ports
|
||||
|
@ -123,6 +123,7 @@ public class Router {
|
||||
|
||||
public String getConfigSetting(String name) { return _config.getProperty(name); }
|
||||
public void setConfigSetting(String name, String value) { _config.setProperty(name, value); }
|
||||
public void removeConfigSetting(String name) { _config.remove(name); }
|
||||
public Set getConfigSettings() { return new HashSet(_config.keySet()); }
|
||||
public Properties getConfigMap() { return _config; }
|
||||
|
||||
|
@ -40,6 +40,7 @@ public class Shitlist {
|
||||
}
|
||||
|
||||
public int getRouterCount() {
|
||||
purge();
|
||||
synchronized (_shitlist) {
|
||||
return _shitlist.size();
|
||||
}
|
||||
@ -98,16 +99,17 @@ public class Shitlist {
|
||||
}
|
||||
}
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<h2>Shitlist</h2>");
|
||||
/**
|
||||
* We already unshitlist on isShitlisted, but this purge
|
||||
* lets us get the correct value when rendering the HTML or
|
||||
* getting the shitlist count. wheee
|
||||
*
|
||||
*/
|
||||
private void purge() {
|
||||
Map shitlist = null;
|
||||
Map causes = null;
|
||||
synchronized (_shitlist) {
|
||||
shitlist = new HashMap(_shitlist);
|
||||
causes = new HashMap(_shitlistCause);
|
||||
}
|
||||
buf.append("<ul>");
|
||||
|
||||
long limit = _context.clock().now() - SHITLIST_DURATION_MS;
|
||||
|
||||
@ -116,17 +118,39 @@ public class Shitlist {
|
||||
Date shitDate = (Date)shitlist.get(key);
|
||||
if (shitDate.getTime() < limit) {
|
||||
unshitlistRouter(key);
|
||||
} else {
|
||||
buf.append("<li><b>").append(key.toBase64()).append("</b> was shitlisted on ");
|
||||
buf.append(shitDate);
|
||||
String cause = (String)causes.get(key);
|
||||
if (cause != null) {
|
||||
buf.append("<br />\n");
|
||||
buf.append(cause);
|
||||
}
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
buf.append("<h2>Shitlist</h2>");
|
||||
Map shitlist = null;
|
||||
Map causes = null;
|
||||
|
||||
purge();
|
||||
|
||||
synchronized (_shitlist) {
|
||||
shitlist = new HashMap(_shitlist);
|
||||
causes = new HashMap(_shitlistCause);
|
||||
}
|
||||
buf.append("<ul>");
|
||||
|
||||
for (Iterator iter = shitlist.keySet().iterator(); iter.hasNext(); ) {
|
||||
Hash key = (Hash)iter.next();
|
||||
Date shitDate = (Date)shitlist.get(key);
|
||||
buf.append("<li><b>").append(key.toBase64()).append("</b>");
|
||||
buf.append(" <a href=\"netdb.jsp#").append(key.toBase64().substring(0, 6)).append("\">(?)</a>");
|
||||
buf.append(" was shitlisted on ");
|
||||
buf.append(shitDate);
|
||||
String cause = (String)causes.get(key);
|
||||
if (cause != null) {
|
||||
buf.append("<br />\n");
|
||||
buf.append(cause);
|
||||
}
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
buf.append("</ul>\n");
|
||||
out.write(buf.toString().getBytes());
|
||||
}
|
||||
|
@ -73,17 +73,6 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
*/
|
||||
private Set _publishingLeaseSets;
|
||||
|
||||
/**
|
||||
* List of keys that we've recently done full searches on and failed.
|
||||
*
|
||||
*/
|
||||
private Set _badKeys;
|
||||
/**
|
||||
* Mapping when (Long) to Hash for keys that are in the _badKeys list.
|
||||
*
|
||||
*/
|
||||
private Map _badKeyDates;
|
||||
|
||||
/**
|
||||
* for the 10 minutes after startup, don't fail db entries so that if we were
|
||||
* offline for a while, we'll have a chance of finding some live peers with the
|
||||
@ -107,78 +96,6 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
_peerSelector = new PeerSelector(_context);
|
||||
_publishingLeaseSets = new HashSet(8);
|
||||
_lastExploreNew = 0;
|
||||
_badKeys = new HashSet();
|
||||
_badKeyDates = new TreeMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* if we do a full search for a key and still fail, don't try again
|
||||
* for another 5 minutes
|
||||
*/
|
||||
private static final long SHITLIST_TIME = 5*60*1000;
|
||||
|
||||
/**
|
||||
* Are we currently avoiding this key?
|
||||
*
|
||||
*/
|
||||
boolean isShitlisted(Hash key) {
|
||||
synchronized (_badKeys) {
|
||||
locked_cleanupShitlist();
|
||||
boolean isShitlisted = _badKeys.contains(key);
|
||||
if (!isShitlisted) return false;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Key " + key.toBase64() + " is shitlisted");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* For some reason, we don't want to try any remote lookups for this key
|
||||
* anytime soon - for instance, we may have just failed to find it after a
|
||||
* full netDb search.
|
||||
*
|
||||
*/
|
||||
void shitlist(Hash key) {
|
||||
synchronized (_badKeys) {
|
||||
locked_cleanupShitlist();
|
||||
boolean wasNew = _badKeys.add(key);
|
||||
if (wasNew) {
|
||||
long when = _context.clock().now();
|
||||
while (_badKeyDates.containsKey(new Long(when)))
|
||||
when++;
|
||||
_badKeyDates.put(new Long(when), key);
|
||||
_log.info("Shitlist " + key.toBase64() + " - new shitlist");
|
||||
} else {
|
||||
_log.info("Shitlist " + key.toBase64() + " - already shitlisted");
|
||||
}
|
||||
}
|
||||
}
|
||||
private void locked_cleanupShitlist() {
|
||||
List old = null;
|
||||
long keepAfter = _context.clock().now() - SHITLIST_TIME;
|
||||
for (Iterator iter = _badKeyDates.keySet().iterator(); iter.hasNext(); ) {
|
||||
Long when = (Long)iter.next();
|
||||
Hash key = (Hash)_badKeyDates.get(when);
|
||||
if (when.longValue() < keepAfter) {
|
||||
if (old == null)
|
||||
old = new ArrayList(4);
|
||||
old.add(when);
|
||||
} else {
|
||||
// ordered
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (old != null) {
|
||||
for (int i = 0; i < old.size(); i++) {
|
||||
Long when = (Long)old.get(i);
|
||||
Hash key = (Hash)_badKeyDates.remove(when);
|
||||
_badKeys.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Cleaning up shitlist: " + _badKeys.size() + " remain after removing "
|
||||
+ (old != null ? old.size() : 0));
|
||||
}
|
||||
|
||||
KBucketSet getKBuckets() { return _kb; }
|
||||
@ -828,10 +745,11 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
}
|
||||
|
||||
private void renderRouterInfo(StringBuffer buf, RouterInfo info, boolean isUs) {
|
||||
String hash = info.getIdentity().getHash().toBase64();
|
||||
if (isUs) {
|
||||
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
|
||||
buf.append("<b>Our info: </b><br />\n");
|
||||
} else {
|
||||
String hash = info.getIdentity().getHash().toBase64();
|
||||
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
|
||||
buf.append("<b>Peer info for:</b> ").append(hash).append("<br />\n");
|
||||
}
|
||||
|
@ -531,9 +531,6 @@ class SearchJob extends JobImpl {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getJobId() + ": State of failed search: " + _state);
|
||||
|
||||
// ok, we totally failed, so don't try again for that key too quickly
|
||||
_facade.shitlist(_state.getTarget());
|
||||
|
||||
if (_keepStats) {
|
||||
long time = getContext().clock().now() - _state.getWhenStarted();
|
||||
getContext().statManager().addRateData("netDb.failedTime", time, 0);
|
||||
|
Reference in New Issue
Block a user