From de3ca2b2efcbe5eec2d3aeb41bd76033d0cd74f5 Mon Sep 17 00:00:00 2001 From: "Ray J. Greenwell" Date: Fri, 23 Aug 2013 16:34:35 -0700 Subject: [PATCH] Final tweaks to the reboot manager. Consolidate warnings and interval scheduling in doWarning(). Don't let the reboot time drift because of delays on the RunQueue.. each warning is scheduled based on absolute time from _nextReboot. doWarning() now takes two args so any subclasses that had overridden it (unlikley beyond PX) will break... PendingShutdownObservers will now get the actual milliseconds until reboot. Basically: after all this, things should essentially work the same except now there is a protected three-arg version of scheduleReboot that lets you schedule an exact time, bypassing the normal round-up to the next highest warning time. --- .../presents/server/RebootManager.java | 47 +++++++------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/com/threerings/presents/server/RebootManager.java b/core/src/main/java/com/threerings/presents/server/RebootManager.java index a12f77b0c..1dcfb1cfa 100644 --- a/core/src/main/java/com/threerings/presents/server/RebootManager.java +++ b/core/src/main/java/com/threerings/presents/server/RebootManager.java @@ -214,23 +214,8 @@ public abstract class RebootManager // note our new reboot time and its initiator _nextReboot = rebootTime; _initiator = initiator; - _rebootSoon = (level > -1); - // maybe issue a warning now - if (level > -1) { - int minutes = (int)((rebootTime - now) / (60L * 1000L)); - broadcast(getRebootMessage("m.reboot_warning", minutes)); - } - - // and schedule our interval to hit the next level at the appropriate time - final int nextLevel = level + 1; - _interval = _omgr.newInterval(new Runnable() { - public void run () { - doWarning(nextLevel); - } - }); - int nextWarning = (nextLevel == warnings.length) ? 0 : warnings[nextLevel]; - _interval.schedule((_nextReboot - (nextWarning * 60L * 1000L)) - now); + doWarning(level, (int)((rebootTime - now) / (60L * 1000L))); } /** @@ -281,9 +266,10 @@ public abstract class RebootManager /** * Do a warning, schedule the next. */ - protected void doWarning (final int level) + protected void doWarning (int level, int minutes) { - _rebootSoon = true; + _rebootSoon = (level > -1); + int[] warnings = getWarnings(); if (level == warnings.length) { if (checkLocks()) { @@ -304,19 +290,21 @@ public abstract class RebootManager } // issue the warning - int minutes = warnings[level]; - broadcast(getRebootMessage("m.reboot_warning", minutes)); - if (level < warnings.length - 1) { - minutes -= warnings[level + 1]; + if (_rebootSoon) { + notifyObservers(level); + broadcast(getRebootMessage("m.reboot_warning", minutes)); } // schedule the next warning - (_interval = _omgr.newInterval(new Runnable() { + final int nextLevel = level + 1; + final int nextMinutes = (nextLevel == warnings.length) ? 0 : warnings[nextLevel]; + _interval = _omgr.newInterval(new Runnable() { public void run () { - doWarning(level + 1); + doWarning(nextLevel, nextMinutes); } - })).schedule(minutes * 60 * 1000); - notifyObservers(level); + }); + _interval.schedule( + Math.max(0L, _nextReboot - (nextMinutes * 60L * 1000L) - System.currentTimeMillis())); } /** @@ -333,7 +321,7 @@ public abstract class RebootManager broadcast("m.reboot_delayed"); (_interval = _omgr.newInterval(new Runnable() { public void run () { - doWarning(getWarnings().length); + doWarning(getWarnings().length, 0); } })).schedule(60 * 1000); return true; @@ -344,9 +332,8 @@ public abstract class RebootManager */ protected void notifyObservers (int level) { - int[] warnings = getWarnings(); - final int warningsLeft = warnings.length - level - 1; - final long msLeft = 1000L * 60L * warnings[level]; + final int warningsLeft = getWarnings().length - level - 1; + final long msLeft = _nextReboot - System.currentTimeMillis(); _observers.apply(new ObserverList.ObserverOp() { public boolean apply (PendingShutdownObserver observer) { observer.shutdownPlanned(warningsLeft, msLeft);