From 8b2889e31764c4766503de0d919fa72e64bd341d Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Sun, 21 Oct 2012 17:14:54 +0000 Subject: [PATCH] - Only fail after all URLs are tried - Move registration from servlet to manager and delay - Fix plugin updates - More logging --- .../src/org/klomp/snark/SnarkManager.java | 25 ++++++++++++ .../src/org/klomp/snark/UpdateHandler.java | 2 +- .../org/klomp/snark/web/I2PSnarkServlet.java | 13 ------- .../router/update/ConsoleUpdateManager.java | 38 +++++++++++++------ .../router/update/PluginUpdateHandler.java | 7 ++-- .../i2p/router/update/PluginUpdateRunner.java | 2 + .../net/i2p/router/update/UpdateRunner.java | 7 +++- .../i2p/router/web/ConfigClientsHandler.java | 11 ++++-- 8 files changed, 69 insertions(+), 36 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 8bae58b52b..4399b5f232 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -27,6 +27,7 @@ import java.util.concurrent.LinkedBlockingQueue; import net.i2p.I2PAppContext; import net.i2p.data.Base64; import net.i2p.data.DataHelper; +import net.i2p.update.*; import net.i2p.util.ConcurrentHashSet; import net.i2p.util.FileUtil; import net.i2p.util.I2PAppThread; @@ -65,6 +66,8 @@ public class SnarkManager implements CompleteListener { private volatile boolean _running; private volatile boolean _stopping; private final Map<String, Tracker> _trackerMap; + private UpdateManager _umgr; + private UpdateHandler _uhandler; public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost"; public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort"; @@ -149,10 +152,28 @@ public class SnarkManager implements CompleteListener { _connectionAcceptor = new ConnectionAcceptor(_util); _monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor", true); _monitor.start(); + // delay until UpdateManager is there + _context.simpleScheduler().addEvent(new Register(), 4*60*1000); // Not required, Jetty has a shutdown hook //_context.addShutdownTask(new SnarkManagerShutdown()); } + /** @since 0.9.4 */ + private class Register implements SimpleTimer.TimedEvent { + public void timeReached() { + if (!_running) + return; + _umgr = _context.updateManager(); + if (_umgr != null) { + _uhandler = new UpdateHandler(_context, _umgr, SnarkManager.this); + _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10); + _log.warn("Registering with update manager"); + } else { + _log.warn("No update manager to register with"); + } + } + } + /* * Called by the webapp at Jetty shutdown. * Stops all torrents. Does not close the tunnel, so the announces have a chance. @@ -160,6 +181,10 @@ public class SnarkManager implements CompleteListener { * Runs inline. */ public void stop() { + if (_umgr != null && _uhandler != null) { + //_uhandler.shutdown(); + _umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT); + } _running = false; _monitor.interrupt(); _connectionAcceptor.halt(); diff --git a/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java b/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java index 7bb41bc2fe..ecb27c55d0 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java +++ b/apps/i2psnark/java/src/org/klomp/snark/UpdateHandler.java @@ -21,7 +21,7 @@ import net.i2p.update.*; * * @since 0.9.4 */ -public class UpdateHandler implements Updater { +class UpdateHandler implements Updater { private final I2PAppContext _context; private final UpdateManager _umgr; private final SnarkManager _smgr; diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 459652e690..e96eefe0b2 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletResponse; import net.i2p.I2PAppContext; import net.i2p.data.Base64; import net.i2p.data.DataHelper; -import net.i2p.update.*; import net.i2p.util.I2PAppThread; import net.i2p.util.Log; @@ -43,7 +42,6 @@ import org.klomp.snark.SnarkManager; import org.klomp.snark.Storage; import org.klomp.snark.Tracker; import org.klomp.snark.TrackerClient; -import org.klomp.snark.UpdateHandler; import org.klomp.snark.dht.DHT; import org.mortbay.jetty.servlet.DefaultServlet; @@ -59,8 +57,6 @@ public class I2PSnarkServlet extends DefaultServlet { private I2PAppContext _context; private Log _log; private SnarkManager _manager; - private UpdateManager _umgr; - private UpdateHandler _uhandler; private static long _nonce; private Resource _resourceBase; private String _themePath; @@ -80,11 +76,6 @@ public class I2PSnarkServlet extends DefaultServlet { configFile = "i2psnark.config"; _manager.loadConfig(configFile); _manager.start(); - _umgr = _context.updateManager(); - if (_umgr != null) { - _uhandler = new UpdateHandler(_context, _umgr, _manager); - _umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10); - } try { _resourceBase = Resource.newResource(_manager.getDataDir().getAbsolutePath()); } catch (IOException ioe) {} @@ -95,10 +86,6 @@ public class I2PSnarkServlet extends DefaultServlet { public void destroy() { if (_manager != null) _manager.stop(); - if (_umgr != null && _uhandler != null) { - //_uhandler.shutdown(); - _umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT); - } super.destroy(); } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java index 1f680fbf6d..5386554954 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/ConsoleUpdateManager.java @@ -62,7 +62,7 @@ public class ConsoleUpdateManager implements UpdateManager { /** active updating tasks, pointing to the next ones to try */ private final Map<UpdateTask, List<RegisteredUpdater>> _downloaders; /** as reported by checkers */ - private final Map<UpdateItem, VersionAvailable> _available; + private final ConcurrentHashMap<UpdateItem, VersionAvailable> _available; /** downloaded but NOT installed */ private final Map<UpdateItem, Version> _downloaded; /** downloaded AND installed */ @@ -406,15 +406,19 @@ public class ConsoleUpdateManager implements UpdateManager { /** * Install a plugin. Non-blocking. * If returns true, then call isUpdateInProgress() in a loop + * @param name if null, a new install * @return true if task started */ - public boolean installPlugin(URI uri) { - String fakeName = Long.toString(_context.random().nextLong()); + public boolean installPlugin(String name, URI uri) { + if (name == null) + name = Long.toString(_context.random().nextLong()); List<URI> uris = Collections.singletonList(uri); - UpdateItem fake = new UpdateItem(PLUGIN_INSTALL, fakeName); + UpdateItem item = new UpdateItem(PLUGIN_INSTALL, name); VersionAvailable va = new VersionAvailable("", "", HTTP, uris); - _available.put(fake, va); - return update(PLUGIN_INSTALL, fakeName); + _available.putIfAbsent(item, va); + if (_log.shouldLog(Log.WARN)) + _log.warn("Install plugin: " + name + ' ' + va); + return update(PLUGIN_INSTALL, name); } /** @@ -479,8 +483,11 @@ public class ConsoleUpdateManager implements UpdateManager { List<URI> updateSources = null; UpdateItem ui = new UpdateItem(type, id); VersionAvailable va = _available.get(ui); - if (va == null) + if (va == null) { + if (_log.shouldLog(Log.WARN)) + _log.warn("No version available for: " + type + ' ' + id); return false; + } List<RegisteredUpdater> sorted = new ArrayList(_registeredUpdaters); Collections.sort(sorted); return retry(ui, va.sourceMap, sorted, maxTime) != null; @@ -505,14 +512,21 @@ public class ConsoleUpdateManager implements UpdateManager { if (t != null) { // race window here // store the remaining ones for retrying - if (_log.shouldLog(Log.INFO)) - _log.info("Starting " + r); + if (_log.shouldLog(Log.INFO)) + _log.info("Starting " + r); _downloaders.put(t, toTry); return t; + } else { + if (_log.shouldLog(Log.WARN)) + _log.warn("Updater refused: " + r + " for " + meth + ' ' + e.getValue()); } } } + if (_log.shouldLog(Log.WARN)) + _log.warn("Nothing left to try for: " + r); } + if (_log.shouldLog(Log.WARN)) + _log.warn("Nothing left to try for: " + ui); return null; } @@ -1097,7 +1111,7 @@ public class ConsoleUpdateManager implements UpdateManager { @Override public String toString() { - return "RegisteredUpdater " + updater.getClass().getSimpleName() + " for " + type + ' ' + method + " @pri " + priority; + return "RegisteredUpdater " + updater.getClass() + " for " + type + ' ' + method + " @pri " + priority; } } @@ -1138,7 +1152,7 @@ public class ConsoleUpdateManager implements UpdateManager { @Override public String toString() { - return "RegisteredChecker " + checker.getClass().getSimpleName() + " for " + type + ' ' + method + " @pri " + priority; + return "RegisteredChecker " + checker.getClass() + " for " + type + ' ' + method + " @pri " + priority; } } @@ -1206,7 +1220,7 @@ public class ConsoleUpdateManager implements UpdateManager { @Override public String toString() { - return "VersionAvailable " + version + ' ' + sourceMap; + return "VersionAvailable \"" + version + "\" " + sourceMap; } } } diff --git a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java index 59a2edc417..3f38724efd 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateHandler.java @@ -70,10 +70,9 @@ class PluginUpdateHandler implements Checker, Updater { return null; Properties props = PluginStarter.pluginProperties(_context, appName); String oldVersion = props.getProperty("version"); - String xpi2pURL = props.getProperty("updateURL"); - if (oldVersion == null || xpi2pURL == null) { - //updateStatus("<b>" + _("Cannot check, plugin {0} is not installed", appName) + "</b>"); - return null; + if (oldVersion == null) { + // assume new install + oldVersion = "0"; } UpdateRunner update = new PluginUpdateRunner(_context, _mgr, updateSources, appName, oldVersion); diff --git a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java index 03e385abe1..ddf4a75a3b 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/PluginUpdateRunner.java @@ -111,6 +111,8 @@ class PluginUpdateRunner extends UpdateRunner { _log.error("Error downloading plugin", t); } } + if (!_updated) + _mgr.notifyTaskFailed(this, "", null); } @Override diff --git a/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java b/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java index bf9b2d4de9..813713220c 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/UpdateRunner.java @@ -167,6 +167,7 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList if (_log.shouldLog(Log.DEBUG)) _log.debug("Attempt failed on " + url, cause); // ignored + _mgr.notifyAttemptFailed(this, url, null); } /** subclasses should override */ @@ -204,10 +205,12 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList /** subclasses should override */ public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) { // don't display bytesTransferred as it is meaningless - _log.error("Update from " + url + " did not download completely (" + + if (_log.shouldLog(Log.WARN)) + _log.warn("Update from " + url + " did not download completely (" + bytesRemaining + " remaining after " + currentAttempt + " tries)"); updateStatus("<b>" + _("Transfer failed from {0}", linkify(url)) + "</b>"); - _mgr.notifyTaskFailed(this, "", null); + _mgr.notifyAttemptFailed(this, url, null); + // update() will call notifyTaskFailed() after last URL } public void headerReceived(String url, int attemptNum, String key, String val) {} 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 06f87e377f..038d61d1bc 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHandler.java @@ -322,7 +322,7 @@ public class ConfigClientsHandler extends FormHandler { addFormError(_("No plugin URL specified.")); return; } - installPlugin(url); + installPlugin(null, url); } private void updatePlugin(String app) { @@ -332,7 +332,7 @@ public class ConfigClientsHandler extends FormHandler { addFormError(_("No update URL specified for {0}",app)); return; } - installPlugin(url); + installPlugin(app, url); } /** @since 0.8.13 */ @@ -349,7 +349,10 @@ public class ConfigClientsHandler extends FormHandler { } catch (InterruptedException ie) {} } - private void installPlugin(String url) { + /** + * @param app null for a new install + */ + private void installPlugin(String app, String url) { ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager(); if (mgr == null) { addFormError("Update manager not registered, cannot install"); @@ -366,7 +369,7 @@ public class ConfigClientsHandler extends FormHandler { addFormError(_("Bad URL {0}", url)); return; } - if (mgr.installPlugin(uri)) + if (mgr.installPlugin(app, uri)) addFormNotice(_("Downloading plugin from {0}", url)); else addFormError("Cannot install, check logs"); -- GitLab