diff --git a/src/main/java/com/threerings/presents/peer/server/PeerManager.java b/src/main/java/com/threerings/presents/peer/server/PeerManager.java index 35030ed4b..635657670 100644 --- a/src/main/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/main/java/com/threerings/presents/peer/server/PeerManager.java @@ -945,10 +945,10 @@ public abstract class PeerManager _clmgr.removeClientObserver(this); // clear our record from the node table - _invoker.postUnit(new WriteOnlyUnit("deleteNode(" + _nodeName + ")") { + _invoker.postUnit(new WriteOnlyUnit("shutdownNode(" + _nodeName + ")") { @Override public void invokePersist () throws Exception { - _noderepo.deleteNode(_nodeName); + _noderepo.shutdownNode(_nodeName); } }); diff --git a/src/main/java/com/threerings/presents/peer/server/persist/NodeRecord.java b/src/main/java/com/threerings/presents/peer/server/persist/NodeRecord.java index 572fd9164..765852065 100644 --- a/src/main/java/com/threerings/presents/peer/server/persist/NodeRecord.java +++ b/src/main/java/com/threerings/presents/peer/server/persist/NodeRecord.java @@ -45,11 +45,12 @@ public class NodeRecord extends PersistentRecord public static final ColumnExp PUBLIC_HOST_NAME = colexp(_R, "publicHostName"); public static final ColumnExp PORT = colexp(_R, "port"); public static final ColumnExp LAST_UPDATED = colexp(_R, "lastUpdated"); + public static final ColumnExp SHUTDOWN = colexp(_R, "shutdown"); // AUTO-GENERATED: FIELDS END /** Increment this value if you modify the definition of this persistent * object in a way that will result in a change to its SQL counterpart. */ - public static final int SCHEMA_VERSION = 1; + public static final int SCHEMA_VERSION = 2; /** The unique name assigned to this node. */ @Id @@ -72,6 +73,10 @@ public class NodeRecord extends PersistentRecord @Column(name="LAST_UPDATED") public Timestamp lastUpdated; + /** Whether or not this node is explicitly shut down. */ + @Column(name="SHUTDOWN") + public boolean shutdown; + /** Used to create a blank instance when loading from the database. */ public NodeRecord () { diff --git a/src/main/java/com/threerings/presents/peer/server/persist/NodeRepository.java b/src/main/java/com/threerings/presents/peer/server/persist/NodeRepository.java index c5a3bcab0..2309b4335 100644 --- a/src/main/java/com/threerings/presents/peer/server/persist/NodeRepository.java +++ b/src/main/java/com/threerings/presents/peer/server/persist/NodeRepository.java @@ -26,12 +26,16 @@ import java.util.Set; import java.sql.Timestamp; +import com.google.common.collect.Lists; + import com.google.inject.Inject; import com.google.inject.Singleton; import com.samskivert.util.StringUtil; +import com.samskivert.depot.expression.SQLExpression; import com.samskivert.depot.DepotRepository; +import com.samskivert.depot.Ops; import com.samskivert.depot.PersistenceContext; import com.samskivert.depot.PersistentRecord; import com.samskivert.depot.Query; @@ -51,26 +55,39 @@ public class NodeRepository extends DepotRepository } /** - * Returns a list of all nodes registered in the repository. + * Returns a list of all nodes registered in the repository that are not explicitly shut down. */ public List loadNodes () { - return loadNodes(""); + return loadNodes("", false); } /** * Returns a list of all nodes registered in the repository with names starting with the given - * string. + * string that are not explicitly shut down. */ public List loadNodes (String namespace) + { + return loadNodes(namespace, false); + } + + /** + * Returns a list of all nodes registered in the repository with names starting with the given + * string, optionally including nodes that are explicitly shut down. + */ + public List loadNodes (String namespace, boolean includeShutdown) { // we specifically avoid caching this query because we want the servers to always see the // most up to date set of nodes Query query = from(NodeRecord.class).noCache(); + List> conditions = Lists.newArrayList(); if (!StringUtil.isBlank(namespace)) { - query = query.where(NodeRecord.NODE_NAME.like(namespace + "%")); + conditions.add(NodeRecord.NODE_NAME.like(namespace + "%")); } - return query.select(); + if (!includeShutdown) { + conditions.add(Ops.not(NodeRecord.SHUTDOWN)); + } + return (conditions.isEmpty() ? query : query.where(conditions)).select(); } /** @@ -93,11 +110,11 @@ public class NodeRepository extends DepotRepository } /** - * Deletes the identified node record. + * Marks the identified node as shut down in its record. */ - public void deleteNode (String nodeName) + public void shutdownNode (String nodeName) { - delete(NodeRecord.getKey(nodeName)); + updatePartial(NodeRecord.getKey(nodeName), NodeRecord.SHUTDOWN, true); } @Override // from DepotRepository