Avoid a concrete dependency on PresentsServer.

ProjectX uses Guice to inject dependencies and this results in some random
manager having a dependency on the concrete server class, which invariably is
getting inject itself at the time this dependency has to be resolved, which
causes circular dependencies.

Guice was able to thread the needle with other sneaky business in some cases,
but also sometimes not. So let's give it a nice interface that it can proxy to
manage this particular circular dependency.
This commit is contained in:
Michael Bayne
2026-02-11 09:59:23 -08:00
parent 89f040768a
commit 938847bea9
2 changed files with 12 additions and 3 deletions
@@ -47,7 +47,7 @@ import static com.threerings.presents.Log.log;
* instance is initialized. * instance is initialized.
*/ */
@Singleton @Singleton
public class PresentsServer public class PresentsServer implements RebootManager.Rebootable
{ {
/** Configures dependencies needed by the Presents services. */ /** Configures dependencies needed by the Presents services. */
public static class PresentsModule extends AbstractModule public static class PresentsModule extends AbstractModule
@@ -27,6 +27,15 @@ import static com.threerings.presents.Log.log;
*/ */
public abstract class RebootManager public abstract class RebootManager
{ {
/** An interface implemented by the server we're going to shut down. We do this to avoid having
* a dependency on PresentsServer directly because that tends to cause cyclic dependencies for
* the real servers (like ProjectX) that use Guice to inject dependencies. */
public static interface Rebootable {
/** Queues up a request to shutdown on the event thread. This method may be safely called
* from any thread. */
void queueShutdown ();
}
/** /**
* An interface for receiving notifications about pending automated shutdowns. * An interface for receiving notifications about pending automated shutdowns.
*/ */
@@ -163,7 +172,7 @@ public abstract class RebootManager
/** /**
* Provides us with our dependencies. * Provides us with our dependencies.
*/ */
protected RebootManager (PresentsServer server, RootDObjectManager omgr) protected RebootManager (Rebootable server, RootDObjectManager omgr)
{ {
_server = server; _server = server;
_omgr = omgr; _omgr = omgr;
@@ -333,7 +342,7 @@ public abstract class RebootManager
} }
/** The server that we're going to reboot. */ /** The server that we're going to reboot. */
protected PresentsServer _server; protected Rebootable _server;
/** Our distributed object manager. */ /** Our distributed object manager. */
protected RootDObjectManager _omgr; protected RootDObjectManager _omgr;