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.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
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
|
* 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() {
|
private void saveChanges() {
|
||||||
|
HashSet unsetKeys = new HashSet(_context.router().getConfigMap().keySet());
|
||||||
if (_config != null) {
|
if (_config != null) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(_config.getBytes())));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(_config.getBytes())));
|
||||||
String line = null;
|
String line = null;
|
||||||
@ -52,12 +55,19 @@ public class ConfigAdvancedHandler extends FormHandler {
|
|||||||
String key = line.substring(0, eq).trim();
|
String key = line.substring(0, eq).trim();
|
||||||
String val = line.substring(eq + 1).trim();
|
String val = line.substring(eq + 1).trim();
|
||||||
_context.router().setConfigSetting(key, val);
|
_context.router().setConfigSetting(key, val);
|
||||||
|
unsetKeys.remove(key);
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
addFormError("Error updating the configuration (IOERROR) - please see the error logs");
|
addFormError("Error updating the configuration (IOERROR) - please see the error logs");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Iterator cleaner = unsetKeys.iterator();
|
||||||
|
while (cleaner.hasNext()) {
|
||||||
|
String unsetKey = (String)cleaner.next();
|
||||||
|
_context.router().removeConfigSetting(unsetKey);
|
||||||
|
}
|
||||||
|
|
||||||
boolean saved = _context.router().saveConfig();
|
boolean saved = _context.router().saveConfig();
|
||||||
if (saved)
|
if (saved)
|
||||||
addFormNotice("Configuration saved successfully");
|
addFormNotice("Configuration saved successfully");
|
||||||
|
@ -29,8 +29,8 @@ public class LogsHelper {
|
|||||||
StringBuffer buf = new StringBuffer(16*1024);
|
StringBuffer buf = new StringBuffer(16*1024);
|
||||||
buf.append("<h2>Most recent console messages:</h2><ul>");
|
buf.append("<h2>Most recent console messages:</h2><ul>");
|
||||||
buf.append("<code>\n");
|
buf.append("<code>\n");
|
||||||
for (int i = 0; i < msgs.size(); i++) {
|
for (int i = msgs.size(); i > 0; i--) {
|
||||||
String msg = (String)msgs.get(i);
|
String msg = (String)msgs.get(i - 1);
|
||||||
buf.append("<li>");
|
buf.append("<li>");
|
||||||
buf.append(msg);
|
buf.append(msg);
|
||||||
buf.append("</li>\n");
|
buf.append("</li>\n");
|
||||||
|
@ -71,9 +71,10 @@ public class SummaryHelper {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public String getMemory() {
|
public String getMemory() {
|
||||||
|
DecimalFormat integerFormatter = new DecimalFormat("###,###,##0");
|
||||||
long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024;
|
long used = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024;
|
||||||
long usedPc = 100 - ((Runtime.getRuntime().freeMemory() * 100) / Runtime.getRuntime().totalMemory());
|
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>
|
<i><jsp:getProperty name="formhandler" property="notices" /></i>
|
||||||
|
|
||||||
<form action="configadvanced.jsp" method="POST">
|
<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 />
|
<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
|
<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
|
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 String getConfigSetting(String name) { return _config.getProperty(name); }
|
||||||
public void setConfigSetting(String name, String value) { _config.setProperty(name, value); }
|
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 Set getConfigSettings() { return new HashSet(_config.keySet()); }
|
||||||
public Properties getConfigMap() { return _config; }
|
public Properties getConfigMap() { return _config; }
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ public class Shitlist {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getRouterCount() {
|
public int getRouterCount() {
|
||||||
|
purge();
|
||||||
synchronized (_shitlist) {
|
synchronized (_shitlist) {
|
||||||
return _shitlist.size();
|
return _shitlist.size();
|
||||||
}
|
}
|
||||||
@ -98,16 +99,17 @@ public class Shitlist {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderStatusHTML(OutputStream out) throws IOException {
|
/**
|
||||||
StringBuffer buf = new StringBuffer(1024);
|
* We already unshitlist on isShitlisted, but this purge
|
||||||
buf.append("<h2>Shitlist</h2>");
|
* lets us get the correct value when rendering the HTML or
|
||||||
|
* getting the shitlist count. wheee
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void purge() {
|
||||||
Map shitlist = null;
|
Map shitlist = null;
|
||||||
Map causes = null;
|
|
||||||
synchronized (_shitlist) {
|
synchronized (_shitlist) {
|
||||||
shitlist = new HashMap(_shitlist);
|
shitlist = new HashMap(_shitlist);
|
||||||
causes = new HashMap(_shitlistCause);
|
|
||||||
}
|
}
|
||||||
buf.append("<ul>");
|
|
||||||
|
|
||||||
long limit = _context.clock().now() - SHITLIST_DURATION_MS;
|
long limit = _context.clock().now() - SHITLIST_DURATION_MS;
|
||||||
|
|
||||||
@ -116,8 +118,31 @@ public class Shitlist {
|
|||||||
Date shitDate = (Date)shitlist.get(key);
|
Date shitDate = (Date)shitlist.get(key);
|
||||||
if (shitDate.getTime() < limit) {
|
if (shitDate.getTime() < limit) {
|
||||||
unshitlistRouter(key);
|
unshitlistRouter(key);
|
||||||
} else {
|
}
|
||||||
buf.append("<li><b>").append(key.toBase64()).append("</b> was shitlisted on ");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
buf.append(shitDate);
|
||||||
String cause = (String)causes.get(key);
|
String cause = (String)causes.get(key);
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
@ -126,7 +151,6 @@ public class Shitlist {
|
|||||||
}
|
}
|
||||||
buf.append("</li>\n");
|
buf.append("</li>\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
buf.append("</ul>\n");
|
buf.append("</ul>\n");
|
||||||
out.write(buf.toString().getBytes());
|
out.write(buf.toString().getBytes());
|
||||||
}
|
}
|
||||||
|
@ -73,17 +73,6 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
|||||||
*/
|
*/
|
||||||
private Set _publishingLeaseSets;
|
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
|
* 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
|
* 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);
|
_peerSelector = new PeerSelector(_context);
|
||||||
_publishingLeaseSets = new HashSet(8);
|
_publishingLeaseSets = new HashSet(8);
|
||||||
_lastExploreNew = 0;
|
_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; }
|
KBucketSet getKBuckets() { return _kb; }
|
||||||
@ -828,10 +745,11 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderRouterInfo(StringBuffer buf, RouterInfo info, boolean isUs) {
|
private void renderRouterInfo(StringBuffer buf, RouterInfo info, boolean isUs) {
|
||||||
|
String hash = info.getIdentity().getHash().toBase64();
|
||||||
if (isUs) {
|
if (isUs) {
|
||||||
|
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
|
||||||
buf.append("<b>Our info: </b><br />\n");
|
buf.append("<b>Our info: </b><br />\n");
|
||||||
} else {
|
} else {
|
||||||
String hash = info.getIdentity().getHash().toBase64();
|
|
||||||
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
|
buf.append("<a name=\"").append(hash.substring(0, 6)).append("\" />");
|
||||||
buf.append("<b>Peer info for:</b> ").append(hash).append("<br />\n");
|
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))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug(getJobId() + ": State of failed search: " + _state);
|
_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) {
|
if (_keepStats) {
|
||||||
long time = getContext().clock().now() - _state.getWhenStarted();
|
long time = getContext().clock().now() - _state.getWhenStarted();
|
||||||
getContext().statManager().addRateData("netDb.failedTime", time, 0);
|
getContext().statManager().addRateData("netDb.failedTime", time, 0);
|
||||||
|
Reference in New Issue
Block a user