From 890ad257e1ef0a7d68718a0e32ff868f2a8d0649 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Mon, 30 Jan 2017 22:05:43 +0000 Subject: [PATCH] Router: Run shutdown tasks in parallel, increase max time for shutdown tasks (ticket #1893) i2psnark: Remove most delay between announces at shutdown --- .../src/org/klomp/snark/SnarkManager.java | 15 ++++++-- router/java/src/net/i2p/router/Router.java | 35 +++++++++++++++---- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index fde46724b6..78dbdf30b5 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -42,6 +42,7 @@ import net.i2p.util.SecureDirectory; import net.i2p.util.SecureFileOutputStream; import net.i2p.util.SimpleTimer; import net.i2p.util.SimpleTimer2; +import net.i2p.util.SystemVersion; import net.i2p.util.Translate; import org.klomp.snark.dht.DHT; @@ -302,6 +303,8 @@ public class SnarkManager implements CompleteListener { * Runs inline. */ public void stop() { + if (_log.shouldWarn()) + _log.warn("Snark stop() begin", new Exception("I did it")); if (_umgr != null && _uhandler != null) { //_uhandler.shutdown(); _umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT); @@ -312,6 +315,8 @@ public class SnarkManager implements CompleteListener { _connectionAcceptor.halt(); _idleChecker.cancel(); stopAllTorrents(true); + if (_log.shouldWarn()) + _log.warn("Snark stop() end"); } /** @since 0.9.1 */ @@ -2580,7 +2585,9 @@ public class SnarkManager implements CompleteListener { stopTorrent(snark, false); // Throttle since every unannounce is now threaded. // How to do this without creating a ton of threads? - try { Thread.sleep(20); } catch (InterruptedException ie) {} + if (count % 8 == 0) { + try { Thread.sleep(20); } catch (InterruptedException ie) {} + } } } if (_util.connected()) { @@ -2593,8 +2600,12 @@ public class SnarkManager implements CompleteListener { _context.simpleTimer2().addEvent(new Disconnector(), 60*1000); addMessage(_t("Closing I2P tunnel after notifying trackers.")); if (finalShutdown) { - try { Thread.sleep(5*1000); } catch (InterruptedException ie) {} + long toWait = 5*1000; + if (SystemVersion.isARM()) + toWait *= 2; + try { Thread.sleep(toWait); } catch (InterruptedException ie) {} } + _util.disconnect(); } else { _util.disconnect(); _stopping = false; diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index bdc107ff60..a45ab6d9d8 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.security.GeneralSecurityException; import java.util.Collection; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -121,6 +122,8 @@ public class Router implements RouterClock.ClockShiftListener { private static final String PROP_JBIGI = "jbigi.loadedResource"; public static final String UPDATE_FILE = "i2pupdate.zip"; + private static final int SHUTDOWN_WAIT_SECS = 60; + private static final String originalTimeZoneID; static { // @@ -955,8 +958,6 @@ public class Router implements RouterClock.ClockShiftListener { int bwLim = Math.min(_context.bandwidthLimiter().getInboundKBytesPerSecond(), _context.bandwidthLimiter().getOutboundKBytesPerSecond()); bwLim = (int)(bwLim * getSharePercentage()); - if (_log.shouldLog(Log.INFO)) - _log.info("Adding capabilities w/ bw limit @ " + bwLim, new Exception("caps")); String force = _context.getProperty(PROP_FORCE_BWCLASS); if (force != null && force.length() > 0) { @@ -1210,6 +1211,7 @@ public class Router implements RouterClock.ClockShiftListener { I2PThread.removeOOMEventListener(_oomListener); // Run the shutdown hooks first in case they want to send some goodbye messages // Maybe we need a delay after this too? + LinkedList<Thread> tasks = new LinkedList<Thread>(); for (Runnable task : _context.getShutdownTasks()) { //System.err.println("Running shutdown task " + task.getClass()); if (_log.shouldLog(Log.WARN)) @@ -1219,15 +1221,34 @@ public class Router implements RouterClock.ClockShiftListener { Thread t = new I2PAppThread(task, "Shutdown task " + task.getClass().getName()); t.setDaemon(true); t.start(); - try { - t.join(10*1000); - } catch (InterruptedException ie) {} - if (t.isAlive()) - _log.logAlways(Log.WARN, "Shutdown task took more than 10 seconds to run: " + task.getClass()); + tasks.add(t); } catch (Throwable t) { _log.log(Log.CRIT, "Error running shutdown task", t); } } + long waitSecs = SHUTDOWN_WAIT_SECS; + if (SystemVersion.isARM()) + waitSecs *= 2; + final long maxWait = System.currentTimeMillis() + (waitSecs *1000); + Thread th; + while ((th = tasks.poll()) != null) { + long toWait = maxWait - System.currentTimeMillis(); + if (toWait <= 0) { + _log.logAlways(Log.WARN, "Shutdown tasks took more than " + waitSecs + " seconds to run"); + tasks.clear(); + break; + } + try { + th.join(toWait); + } catch (InterruptedException ie) {} + if (th.isAlive()) { + _log.logAlways(Log.WARN, "Shutdown task took more than " + waitSecs + " seconds to run: " + th.getName()); + tasks.clear(); + break; + } else if (_log.shouldInfo()) { + _log.info("Shutdown task complete: " + th.getName()); + } + } // Set the last version to the current version, since 0.8.13 if (!RouterVersion.VERSION.equals(_config.get("router.previousVersion"))) { -- GitLab