diff --git a/src/java/com/threerings/crowd/chat/server/ChatChannelManager.java b/src/java/com/threerings/crowd/chat/server/ChatChannelManager.java index 111b297db..ae2a3af24 100644 --- a/src/java/com/threerings/crowd/chat/server/ChatChannelManager.java +++ b/src/java/com/threerings/crowd/chat/server/ChatChannelManager.java @@ -31,8 +31,6 @@ import com.google.inject.Inject; import com.samskivert.util.ArrayIntSet; import com.samskivert.util.IntSet; -import com.samskivert.util.Interval; -import com.samskivert.util.Lifecycle; import com.threerings.util.Name; @@ -59,7 +57,7 @@ import static com.threerings.crowd.Log.log; * Handles chat channel services. */ public abstract class ChatChannelManager - implements ChannelSpeakProvider, Lifecycle.ShutdownComponent + implements ChannelSpeakProvider { /** * When a body becomes a member of a channel, this method should be called so that any server @@ -111,30 +109,19 @@ public abstract class ChatChannelManager }); } - // from interface Lifecycle.Shutdowner - public void shutdown () - { - // stop our channel closer; always be closing... except now - _closer.cancel(); - _closer = null; - } - /** * Creates our singleton manager and registers our invocation service. */ - @Inject protected ChatChannelManager (PresentsDObjectMgr omgr, InvocationManager invmgr, - Lifecycle cycle) + @Inject protected ChatChannelManager (PresentsDObjectMgr omgr, InvocationManager invmgr) { invmgr.registerDispatcher(new ChannelSpeakDispatcher(this), CrowdCodes.CROWD_GROUP); - cycle.addComponent(this); - // create and start our idle channel closer (always be closing) - _closer = new Interval(omgr) { - @Override public void expired () { + // create and start our idle channel closer; this will run as long as omgr is alive + omgr.newInterval(new Runnable() { + public void run () { closeIdleChannels(); } - }; - _closer.schedule(IDLE_CHANNEL_CHECK_PERIOD, true); + }).schedule(IDLE_CHANNEL_CHECK_PERIOD, true); } /** @@ -391,9 +378,6 @@ public abstract class ChatChannelManager public long lastMessage; } - /** Used to close channels that have not had any activity in a few minutes. */ - protected Interval _closer; - /** Contains pending messages for all channels currently being resolved. */ protected Map> _resolving = Maps.newHashMap(); diff --git a/src/java/com/threerings/crowd/server/PlaceManager.java b/src/java/com/threerings/crowd/server/PlaceManager.java index 08148ca85..f21c0d1ba 100644 --- a/src/java/com/threerings/crowd/server/PlaceManager.java +++ b/src/java/com/threerings/crowd/server/PlaceManager.java @@ -683,14 +683,12 @@ public class PlaceManager // queue up a shutdown interval, unless we've already got one. long idlePeriod = idleUnloadPeriod(); if (idlePeriod > 0L && _shutdownInterval == null) { - _shutdownInterval = new Interval(_omgr) { - @Override - public void expired () { + _shutdownInterval = _omgr.newInterval(new Runnable() { + public void run () { log.debug("Unloading idle place '" + where() + "'."); shutdown(); } - }; - _shutdownInterval.schedule(idlePeriod); + }).schedule(idlePeriod); } } diff --git a/src/java/com/threerings/presents/dobj/RootDObjectManager.java b/src/java/com/threerings/presents/dobj/RootDObjectManager.java index 10c9dce69..187cf5c2c 100644 --- a/src/java/com/threerings/presents/dobj/RootDObjectManager.java +++ b/src/java/com/threerings/presents/dobj/RootDObjectManager.java @@ -21,6 +21,7 @@ package com.threerings.presents.dobj; +import com.samskivert.util.Interval; import com.samskivert.util.RunQueue; /** @@ -53,4 +54,16 @@ public interface RootDObjectManager extends DObjectManager, RunQueue * @param oid The object id of the distributed object to be destroyed. */ void destroyObject (int oid); + + /** + * Creates an {@link Interval} that runs the supplied runnable. If the root omgr is shutdown + * before the interval expires (or if the interval is scheduled to repeat), it will be + * automatically cancelled. This makes it easy to schedule fire-and-forget intervals: + * + *
+     * _omgr.newInterval(someRunnable).schedule(500); // one shot
+     * Interval ival = _omgr.newInterval(someRunnable).schedule(500, true); // repeater
+     * 
+ */ + Interval newInterval (Runnable action); } diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java index c5f8fc057..178fa9a3c 100644 --- a/src/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/java/com/threerings/presents/peer/server/PeerManager.java @@ -281,8 +281,12 @@ public abstract class PeerManager // register ourselves as a client observer _clmgr.addClientObserver(this); - // and start our peer refresh interval - _peerRefresher.schedule(5000L, 60*1000L); + // and start our peer refresh interval (this lives for the lifetime of the server) + _omgr.newInterval(new Runnable() { + public void run () { + refreshPeers(); + } + }).schedule(5000L, 60*1000L); // give derived classes an easy way to get in on the init action didInit(); @@ -773,9 +777,6 @@ public abstract class PeerManager _invmgr.clearDispatcher(_nodeobj.peerService); } - // stop our peer refresher interval - _peerRefresher.cancel(); - // clear out our client observer registration _clmgr.removeClientObserver(this); @@ -1187,9 +1188,8 @@ public abstract class PeerManager _remoids = (ArrayIntSet)_suboids.clone(); // schedule a timeout to act if something goes wrong - (_timeout = new Interval(_omgr) { - @Override - public void expired () { + _timeout = _omgr.newInterval(new Runnable () { + public void run () { log.warning("Lock handler timed out, acting anyway", "lock", _lock, "acquire", _acquire); _stats.lockTimeouts++; @@ -1372,13 +1372,6 @@ public abstract class PeerManager } }; - // (this need not use a runqueue as all it will do is post an invoker unit) - protected Interval _peerRefresher = new Interval() { - @Override public void expired () { - refreshPeers(); - } - }; - protected String _nodeName, _sharedSecret; protected NodeRecord _self; protected NodeObject _nodeobj; diff --git a/src/java/com/threerings/presents/server/ClientManager.java b/src/java/com/threerings/presents/server/ClientManager.java index 62c2d8e81..38aab6366 100644 --- a/src/java/com/threerings/presents/server/ClientManager.java +++ b/src/java/com/threerings/presents/server/ClientManager.java @@ -35,7 +35,6 @@ import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Singleton; -import com.samskivert.util.Interval; import com.samskivert.util.Lifecycle; import com.samskivert.util.ObserverList; import com.samskivert.util.StringUtil; @@ -337,13 +336,13 @@ public class ClientManager // from interface Lifecycle.Component public void init () { - // start up an interval that will check for and flush expired sessions - _flushSessions = new Interval(_omgr) { - @Override public void expired () { + // start up an interval that will check for and flush expired sessions (this will be + // canceled when the omgr shuts down) + _omgr.newInterval(new Runnable() { + public void run () { flushSessions(); } - }; - _flushSessions.schedule(SESSION_FLUSH_INTERVAL, true); + }).schedule(SESSION_FLUSH_INTERVAL, true); } // from interface Lifecycle.Component @@ -351,8 +350,6 @@ public class ClientManager { log.info("Client manager shutting down", "ccount", _usermap.size()); - _flushSessions.cancel(); - // inform all of our clients that they are being shut down synchronized (_usermap) { for (PresentsSession pc : _usermap.values()) { @@ -625,9 +622,6 @@ public class ClientManager /** Tracks registered {@link ClientObserver}s. */ protected ObserverList _clobservers = ObserverList.newSafeInOrder(); - /** Interval to flush expired sessions. */ - protected Interval _flushSessions; - // our injected dependencies @Inject protected PresentsDObjectMgr _omgr; diff --git a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java index 8c657a1fc..08301bf4a 100644 --- a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java +++ b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java @@ -276,6 +276,20 @@ public class PresentsDObjectMgr postEvent(new ObjectDestroyedEvent(oid)); } + // from interface RootDObjectManager + public Interval newInterval (final Runnable action) + { + return new Interval(this) { + public void expired () { + if (isRunning()) { + action.run(); + } else { + cancel(); + } + } + }; + } + /** * Returns the object in the object table with the specified oid or null if no object has that * oid. Be sure only to call this function from the dobjmgr thread and not to do anything funny diff --git a/src/java/com/threerings/presents/server/RebootManager.java b/src/java/com/threerings/presents/server/RebootManager.java index 9af15e0a8..70e5f3ec8 100644 --- a/src/java/com/threerings/presents/server/RebootManager.java +++ b/src/java/com/threerings/presents/server/RebootManager.java @@ -154,12 +154,11 @@ public abstract class RebootManager // should issue the first pre-reboot warning _rebootSoon = false; long firstWarnTime = (_nextReboot - (WARNINGS[0] * 60 * 1000)) - now; - _interval = new Interval(_omgr) { - @Override public void expired () { + _interval = _omgr.newInterval(new Runnable() { + public void run () { doWarning(0); } - }; - _interval.schedule(firstWarnTime); + }).schedule(firstWarnTime); } /** @@ -271,12 +270,11 @@ public abstract class RebootManager } // schedule the next warning - _interval = new Interval(_omgr) { - @Override public void expired () { + _interval = _omgr.newInterval(new Runnable() { + public void run () { doWarning(level + 1); } - }; - _interval.schedule(minutes * 60 * 1000); + }).schedule(minutes * 60 * 1000); notifyObservers(level); } @@ -292,12 +290,11 @@ public abstract class RebootManager log.info("Reboot delayed due to outstanding locks", "locks", _rebootLocks.elements()); broadcast("m.reboot_delayed"); - _interval = new Interval(_omgr) { - @Override public void expired () { + _interval = _omgr.newInterval(new Runnable() { + public void run () { doWarning(WARNINGS.length); } - }; - _interval.schedule(60 * 1000); + }).schedule(60 * 1000); return true; } diff --git a/src/java/com/threerings/presents/server/ReportManager.java b/src/java/com/threerings/presents/server/ReportManager.java index 47e0c207e..cd5700f40 100644 --- a/src/java/com/threerings/presents/server/ReportManager.java +++ b/src/java/com/threerings/presents/server/ReportManager.java @@ -26,11 +26,10 @@ import com.google.common.collect.Multimap; import com.google.inject.Inject; import com.google.inject.Singleton; -import com.samskivert.util.Interval; import com.samskivert.util.RunQueue; import com.samskivert.util.StringUtil; -import com.threerings.presents.annotation.EventQueue; +import com.threerings.presents.dobj.RootDObjectManager; import static com.threerings.presents.Log.log; @@ -69,15 +68,13 @@ public class ReportManager */ public void activatePeriodicReport () { - // queue up an interval which will generate reports - _reportInterval = new Interval(_dobjq) { - @Override - public void expired () { + // queue up an interval which will generate reports as long as the omgr is alive + _omgr.newInterval(new Runnable() { + public void run () { logReport(LOG_REPORT_HEADER + generateReport(DEFAULT_TYPE, System.currentTimeMillis(), true)); } - }; - _reportInterval.schedule(REPORT_INTERVAL, true); + }).schedule(REPORT_INTERVAL, true); } /** @@ -178,9 +175,6 @@ public class ReportManager log.info(report); } - /** Our interval that generates "state of server" reports. */ - protected Interval _reportInterval; - /** The time at which the server was started. */ protected long _serverStartTime = System.currentTimeMillis(); @@ -190,8 +184,8 @@ public class ReportManager /** Used to generate "state of server" reports. */ protected Multimap _reporters = ArrayListMultimap.create(); - /** We need to queue up our reporting interval on this feller. */ - @Inject protected @EventQueue RunQueue _dobjq; + /** We use the root omgr to queue up our reporting interval. */ + @Inject protected RootDObjectManager _omgr; /** The frequency with which we generate "state of server" reports. */ protected static final long REPORT_INTERVAL = 15 * 60 * 1000L;