From 2c45378c6d99e8d3055dd3a411a0a810044d4126 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 22 Mar 2015 10:08:48 +0000 Subject: [PATCH] Console: Better status feedback on manual reseed from URL Reseed: Better status feedback and cleanup in summary bar --- .../i2p/router/web/ConfigClientsHandler.java | 4 +-- .../i2p/router/web/ConfigReseedHandler.java | 30 ++++++++--------- .../src/net/i2p/router/web/FormHandler.java | 11 +++++++ history.txt | 8 +++++ .../src/net/i2p/router/RouterVersion.java | 2 +- .../networkdb/reseed/ReseedChecker.java | 33 ++++++++++++++++++- .../i2p/router/networkdb/reseed/Reseeder.java | 15 ++++++--- 7 files changed, 79 insertions(+), 24 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java index d957938ff..dc0983ea2 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java @@ -450,13 +450,13 @@ public class ConfigClientsHandler extends FormHandler { ConsoleUpdateManager mgr = UpdateHandler.updateManager(_context); if (mgr == null) return; - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 20; i++) { if (!mgr.isUpdateInProgress(PLUGIN)) { tmp.delete(); break; } try { - Thread.sleep(1000); + Thread.sleep(500); } catch (InterruptedException ie) {} } String status = mgr.getStatus(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java index df7a7983a..2dd4330a1 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigReseedHandler.java @@ -49,25 +49,23 @@ public class ConfigReseedHandler extends FormHandler { addFormError(_("Reseeding is already in progress")); } else { // wait a while for completion but not forever - for (int i = 0; i < 20; i++) { + for (int i = 0; i < 40; i++) { try { - Thread.sleep(1000); + Thread.sleep(500); } catch (InterruptedException ie) {} - if (!_context.netDb().reseedChecker().inProgress()) { - String status = _context.netDb().reseedChecker().getStatus(); - if (status.length() > 0) - addFormNotice(status); - else - addFormNotice(_("Ressed complete, check summary bar for status")); - return; - } + if (!_context.netDb().reseedChecker().inProgress()) + break; } - if (_context.netDb().reseedChecker().inProgress()) { - String status = _context.netDb().reseedChecker().getStatus(); - if (status.length() > 0) - addFormNotice(status); - else - addFormNotice(_("Ressed in progress, check summary bar for status")); + String status = _context.netDb().reseedChecker().getStatus(); + String error = _context.netDb().reseedChecker().getError(); + if (error.length() > 0) { + addFormErrorNoEscape(error); + } else if (status.length() > 0) { + addFormNoticeNoEscape(status); + } else if (_context.netDb().reseedChecker().inProgress()) { + addFormNotice(_("Reseed in progress, check summary bar for status")); + } else { + addFormNotice(_("Reseed complete, check summary bar for status")); } } } catch (IllegalArgumentException iae) { diff --git a/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java index ec22ae8b6..a56f8f7ad 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/FormHandler.java @@ -152,6 +152,17 @@ public abstract class FormHandler { _notices.add(msg); } + /** + * Add an error message to display + * Use if it includes a link or other formatting. + * Does not escape '<' and '>' before queueing + * @since 0.9.19 + */ + protected void addFormErrorNoEscape(String msg) { + if (msg == null) return; + _errors.add(msg); + } + /** * Display everything, wrap it in a div for consistent presentation * diff --git a/history.txt b/history.txt index 66513665c..134763306 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,11 @@ +2015-03-22 zzz + * Console: Better status feedback on manual reseed from URL + * NetDB: Don't become floodfill w/o ECDSA support + * Reseed: Better status feedback and cleanup in summary bar + +2015-03-21 zzz + * Console: Support plugin installation from local file + 2015-03-20 zzz * Reseed: - Move multipart form support from susimail to jetty-i2p.jar diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index f2522cd4e..7ca1a3ec2 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 9; + public final static long BUILD = 10; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java index b65bf700f..df4f31300 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/ReseedChecker.java @@ -6,9 +6,11 @@ import java.io.IOException; import java.net.URL; import java.util.concurrent.atomic.AtomicBoolean; +import net.i2p.data.DataHelper; import net.i2p.router.RouterContext; import net.i2p.util.Addresses; import net.i2p.util.Log; +import net.i2p.util.SimpleTimer; /** * Moved from RouterConsoleRunner.java @@ -31,6 +33,7 @@ public class ReseedChecker { private volatile String _lastError = ""; public static final int MINIMUM = 50; + private static final long STATUS_CLEAN_TIME = 20*60*1000; /** * All reseeding must be done through this instance. @@ -123,6 +126,8 @@ public class ReseedChecker { reseeder.requestReseed(url); return true; } catch (IllegalArgumentException iae) { + if (iae.getMessage() != null) + setError(DataHelper.escapeHTML(iae.getMessage())); done(); throw iae; } catch (Throwable t) { @@ -150,6 +155,11 @@ public class ReseedChecker { try { Reseeder reseeder = new Reseeder(_context, this); return reseeder.requestReseed(in); + } catch (IOException ioe) { + if (ioe.getMessage() != null) + setError(DataHelper.escapeHTML(ioe.getMessage())); + done(); + throw ioe; } finally { done(); } @@ -174,11 +184,13 @@ public class ReseedChecker { */ void done() { _inProgress.set(false); + _context.simpleScheduler().addEvent(new StatusCleaner(_lastStatus, _lastError), STATUS_CLEAN_TIME); } /** * Status from current reseed attempt, * probably empty if no reseed in progress. + * May include HTML. * * @return non-null, may be empty * @since 0.9 @@ -198,7 +210,8 @@ public class ReseedChecker { } /** - * Error from last or current reseed attempt + * Error from last or current reseed attempt. + * May include HTML. * * @return non-null, may be empty * @since 0.9 @@ -217,4 +230,22 @@ public class ReseedChecker { _lastError = s; } + /** + * @since 0.9.19 + */ + private class StatusCleaner implements SimpleTimer.TimedEvent { + private final String _status, _error; + + public StatusCleaner(String status, String error) { + _status = status; + _error = error; + } + + public void timeReached() { + if (_status.equals(getStatus())) + setStatus(""); + if (_error.equals(getError())) + setError(""); + } + } } diff --git a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java index 194d28b4d..1cfe767be 100644 --- a/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java +++ b/router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java @@ -167,6 +167,8 @@ public class Reseeder { * @since 0.9.19 */ int requestReseed(InputStream in) throws IOException { + _checker.setError(""); + _checker.setStatus("Reseeding from file"); byte[] su3Magic = DataHelper.getASCII(SU3File.MAGIC); byte[] zipMagic = new byte[] { 0x50, 0x4b, 0x03, 0x04 }; int len = Math.max(su3Magic.length, zipMagic.length); @@ -282,7 +284,7 @@ public class Reseeder { } else { total = reseed(false); } - if (total >= 50) { + if (total >= 20) { System.out.println("Reseed complete, " + total + " received"); _checker.setError(""); } else if (total > 0) { @@ -294,12 +296,15 @@ public class Reseeder { System.out.println( "Ensure that nothing blocks outbound HTTP, check the logs, " + "and if nothing helps, read the FAQ about reseeding manually."); + String old = _checker.getError(); _checker.setError(_("Reseed failed.") + ' ' + - _("See {0} for help.", - "" + _("reseed configuration page") + "")); + _("See {0} for help.", + "" + _("reseed configuration page") + "") + + "
" + old); } _isRunning = false; - _checker.setStatus(""); + // ReseedChecker will set timer to clean up + //_checker.setStatus(""); _context.router().eventLog().addEvent(EventLog.RESEED, Integer.toString(total)); } @@ -328,6 +333,8 @@ public class Reseeder { _log.warn("EepGet failed on " + url, cause); else _log.logAlways(Log.WARN, "EepGet failed on " + url + " : " + cause); + if (cause != null && cause.getMessage() != null) + _checker.setError(DataHelper.escapeHTML(cause.getMessage())); } public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {}