* Soft restart:

- Allow NTP to reinitialize clock after the comm system
      in the first minute of uptime
    - Fix i2ptunnels not restarting
    - Increase minimum forward clock shift for soft restart
    - Reduce minimum backward clock shift for soft restart
    - Signal the I2CP client with a different message when restarting
    - I2CP client reconnects when receiving restart message
This commit is contained in:
zzz
2011-08-19 15:34:30 +00:00
parent 26c744ca45
commit c5e74fefe5
9 changed files with 65 additions and 13 deletions

View File

@ -12,6 +12,7 @@ package net.i2p.client;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.data.i2cp.DisconnectMessage; import net.i2p.data.i2cp.DisconnectMessage;
import net.i2p.data.i2cp.I2CPMessage; import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log; import net.i2p.util.Log;
/** /**
@ -27,7 +28,26 @@ class DisconnectMessageHandler extends HandlerImpl {
public void handleMessage(I2CPMessage message, I2PSessionImpl session) { public void handleMessage(I2CPMessage message, I2PSessionImpl session) {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Handle message " + message); _log.debug("Handle message " + message);
session.propogateError(((DisconnectMessage)message).getReason(), new I2PSessionException("Disconnect Message received")); String reason = ((DisconnectMessage)message).getReason();
session.propogateError(reason, new I2PSessionException("Disconnect Message received"));
session.destroySession(false); session.destroySession(false);
if (reason.contains("restart")) {
Thread t = new I2PAppThread(new Reconnector(session), "Reconnect " + session, true);
t.start();
}
}
/** @since 0.8.8 */
private static class Reconnector implements Runnable {
private final I2PSessionImpl _session;
public Reconnector(I2PSessionImpl session) {
_session = session;
}
public void run() {
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
_session.reconnect();
}
} }
} }

View File

@ -1,3 +1,13 @@
2011-08-19 zzz
* Soft restart:
- Allow NTP to reinitialize clock after the comm system
in the first minute of uptime
- Fix i2ptunnels not restarting
- Increase minimum forward clock shift for soft restart
- Reduce minimum backward clock shift for soft restart
- Signal the I2CP client with a different message when restarting
- I2CP client reconnects when receiving restart message
2011-08-17 kytv 2011-08-17 kytv
* Fix #506: Don't attempt to load systray4j when using a 64bit JVM * Fix #506: Don't attempt to load systray4j when using a 64bit JVM
in Windows. in Windows.

View File

@ -94,4 +94,7 @@ public abstract class ClientManagerFacade implements Service {
public abstract SessionConfig getClientSessionConfig(Destination dest); public abstract SessionConfig getClientSessionConfig(Destination dest);
public abstract SessionKeyManager getClientSessionKeyManager(Hash dest); public abstract SessionKeyManager getClientSessionKeyManager(Hash dest);
public void renderStatusHTML(Writer out) throws IOException { } public void renderStatusHTML(Writer out) throws IOException { }
/** @since 0.8.8 */
public abstract void shutdown(String msg);
} }

View File

@ -36,6 +36,7 @@ public class DummyClientManagerFacade extends ClientManagerFacade {
public void startup() {} public void startup() {}
public void stopAcceptingClients() { } public void stopAcceptingClients() { }
public void shutdown() {} public void shutdown() {}
public void shutdown(String msg) {}
public void restart() {} public void restart() {}
public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered) {} public void messageDeliveryStatusUpdate(Destination fromDest, MessageId id, boolean delivered) {}

View File

@ -1308,7 +1308,8 @@ public class Router implements RouterClock.ClockShiftListener {
_started = _context.clock().now(); _started = _context.clock().now();
_log.error("Stopping the router for a restart..."); _log.error("Stopping the router for a restart...");
_log.logAlways(Log.WARN, "Stopping the client manager"); _log.logAlways(Log.WARN, "Stopping the client manager");
try { _context.clientManager().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error stopping the client manager", t); } // NOTE: DisconnectMessageHandler keys off "restart"
try { _context.clientManager().shutdown("Router restart"); } catch (Throwable t) { _log.log(Log.CRIT, "Error stopping the client manager", t); }
_log.logAlways(Log.WARN, "Stopping the comm system"); _log.logAlways(Log.WARN, "Stopping the comm system");
try { _context.messageRegistry().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the message registry", t); } try { _context.messageRegistry().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the message registry", t); }
try { _context.commSystem().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the comm system", t); } try { _context.commSystem().restart(); } catch (Throwable t) { _log.log(Log.CRIT, "Error restarting the comm system", t); }

View File

@ -40,11 +40,13 @@ public class RouterClock extends Clock {
private int _lastStratum; private int _lastStratum;
/** /**
* If the system clock shifts by this much (positive or negative), * If the system clock shifts by this much,
* call the callback, we probably need a soft restart. * call the callback, we probably need a soft restart.
* @since 0.8.8 * @since 0.8.8
*/ */
private static final long MASSIVE_SHIFT = 75*1000; private static final long MASSIVE_SHIFT_FORWARD = 150*1000;
private static final long MASSIVE_SHIFT_BACKWARD = 61*1000;
private final Set<ClockShiftListener> _shiftListeners; private final Set<ClockShiftListener> _shiftListeners;
private volatile long _lastShiftNanos; private volatile long _lastShiftNanos;
@ -137,7 +139,11 @@ public class RouterClock extends Clock {
} // check sanity } // check sanity
} }
if (_alreadyChanged) { // In first minute, allow a lower (better) stratum to do a step adjustment after
// a previous step adjustment.
// This allows NTP to trump a peer offset after a soft restart
if (_alreadyChanged &&
(stratum >= _lastStratum || _startedOn - System.currentTimeMillis() > 60*1000)) {
// Update the target offset, slewing will take care of the rest // Update the target offset, slewing will take care of the rest
if (delta > 15*1000) if (delta > 15*1000)
getLog().error("Warning - Updating target clock offset to " + offsetMs + "ms from " + _offset + "ms, Stratum " + stratum); getLog().error("Warning - Updating target clock offset to " + offsetMs + "ms from " + _offset + "ms, Stratum " + stratum);
@ -192,8 +198,8 @@ public class RouterClock extends Clock {
// copy the global, so two threads don't both increment or decrement _offset // copy the global, so two threads don't both increment or decrement _offset
long offset = _offset; long offset = _offset;
long sinceLastSlewed = systemNow - _lastSlewed; long sinceLastSlewed = systemNow - _lastSlewed;
if (sinceLastSlewed >= MASSIVE_SHIFT || if (sinceLastSlewed >= MASSIVE_SHIFT_FORWARD ||
sinceLastSlewed <= 0 - MASSIVE_SHIFT) { sinceLastSlewed <= 0 - MASSIVE_SHIFT_BACKWARD) {
_lastSlewed = systemNow; _lastSlewed = systemNow;
notifyMassive(sinceLastSlewed); notifyMassive(sinceLastSlewed);
} else if (sinceLastSlewed >= MAX_SLEW) { } else if (sinceLastSlewed >= MAX_SLEW) {
@ -224,7 +230,7 @@ public class RouterClock extends Clock {
long nowNanos = System.nanoTime(); long nowNanos = System.nanoTime();
// try to prevent dups, not guaranteed // try to prevent dups, not guaranteed
// nanoTime() isn't guaranteed to be monotonic either :( // nanoTime() isn't guaranteed to be monotonic either :(
if (nowNanos < _lastShiftNanos + MASSIVE_SHIFT) if (nowNanos < _lastShiftNanos + MASSIVE_SHIFT_FORWARD)
return; return;
_lastShiftNanos = nowNanos; _lastShiftNanos = nowNanos;

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 22; public final static long BUILD = 23;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = "-rc"; public final static String EXTRA = "-rc";

View File

@ -86,7 +86,7 @@ class ClientManager {
} }
public void restart() { public void restart() {
shutdown(); shutdown("Router restart");
// to let the old listener die // to let the old listener die
try { Thread.sleep(2*1000); } catch (InterruptedException ie) {} try { Thread.sleep(2*1000); } catch (InterruptedException ie) {}
@ -96,7 +96,10 @@ class ClientManager {
startListeners(port); startListeners(port);
} }
public void shutdown() { /**
* @param msg message to send to the clients
*/
public void shutdown(String msg) {
_isStarted = false; _isStarted = false;
_log.info("Shutting down the ClientManager"); _log.info("Shutting down the ClientManager");
if (_listener != null) if (_listener != null)
@ -116,7 +119,7 @@ class ClientManager {
} }
for (Iterator<ClientConnectionRunner> iter = runners.iterator(); iter.hasNext(); ) { for (Iterator<ClientConnectionRunner> iter = runners.iterator(); iter.hasNext(); ) {
ClientConnectionRunner runner = iter.next(); ClientConnectionRunner runner = iter.next();
runner.disconnectClient("Router shutdown", Log.WARN); runner.disconnectClient(msg, Log.WARN);
} }
} }

View File

@ -58,8 +58,16 @@ public class ClientManagerFacadeImpl extends ClientManagerFacade implements Inte
} }
public void shutdown() { public void shutdown() {
shutdown("Router shutdown");
}
/**
* @param msg message to send to the clients
* @since 0.8.8
*/
public void shutdown(String msg) {
if (_manager != null) if (_manager != null)
_manager.shutdown(); _manager.shutdown(msg);
} }
public void restart() { public void restart() {