From 0400974701bd1cbfe35bd2dbf5f5a67d574ed8f5 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 4 Oct 2011 22:06:39 +0000 Subject: [PATCH] Include a "region" column in the nodes table. Peers in different regions must use the public host name to connect to each other. This is in support of adding servers in different EC2 regions to Spiral Knights (it's looking like this solution will be less complicated than trying to create a cross-region shared DNS system). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6722 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/peer/server/PeerManager.java | 43 +++++++++++++++++-- .../presents/peer/server/PeerNode.java | 6 ++- .../peer/server/persist/NodeRecord.java | 22 +++++++++- 3 files changed, 64 insertions(+), 7 deletions(-) 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 635657670..07f25769c 100644 --- a/src/main/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/main/java/com/threerings/presents/peer/server/PeerManager.java @@ -288,8 +288,36 @@ public abstract class PeerManager * @param nodeNamespace The namespace for nodes to peer with. This node will connect to other * nodes with the same prefix from the NODES table. */ - public void init (String nodeName, String sharedSecret, - String hostName, String publicHostName, int port, String nodeNamespace) + public void init ( + String nodeName, String sharedSecret, String hostName, + String publicHostName, int port, String nodeNamespace) + { + init(nodeName, sharedSecret, hostName, publicHostName, null, port, nodeNamespace); + } + + /** + * Initializes this peer manager and initiates the process of connecting to its peer nodes. + * This will also reconfigure the ConnectionManager and ClientManager with peer related bits, + * so this should not be called until after the main server has set up its client + * factory and authenticator. + * + * @param nodeName this node's unique name. + * @param sharedSecret a shared secret used to allow the peers to authenticate with one + * another. + * @param hostName the DNS name of the server running this node. + * @param publicHostName if non-null, a separate public DNS hostname by which the node is to + * be known to normal clients (we may want inter-peer communication to take place over a + * different network than the communication between real clients and the various peer + * servers). + * @param region the region in which the node lives, which may be null. Nodes in different + * regions must connect to each other through the public host name. + * @param port the port on which other nodes should connect to us. + * @param nodeNamespace The namespace for nodes to peer with. This node will connect to other + * nodes with the same prefix from the NODES table. + */ + public void init ( + String nodeName, String sharedSecret, String hostName, String publicHostName, + String region, int port, String nodeNamespace) { _nodeNamespace = nodeNamespace; _nodeName = nodeName; @@ -313,7 +341,8 @@ public abstract class PeerManager // register ourselves with the node table _self = new NodeRecord( - _nodeName, hostName, (publicHostName == null) ? hostName : publicHostName, port); + _nodeName, hostName, (publicHostName == null) ? hostName : publicHostName, + region, port); _invoker.postUnit(new WriteOnlyUnit("registerNode(" + _self + ")") { @Override public void invokePersist () throws Exception { @@ -1254,6 +1283,14 @@ public abstract class PeerManager return new PeerCreds(_nodeName, _sharedSecret); } + /** + * Returns the region in which the local node exists. + */ + protected String getRegion () + { + return _self.region; + } + /** * Called when we hear about a client logging on to another node. */ diff --git a/src/main/java/com/threerings/presents/peer/server/PeerNode.java b/src/main/java/com/threerings/presents/peer/server/PeerNode.java index 0b8bf35b6..1a1b3475c 100644 --- a/src/main/java/com/threerings/presents/peer/server/PeerNode.java +++ b/src/main/java/com/threerings/presents/peer/server/PeerNode.java @@ -127,7 +127,9 @@ public class PeerNode public void refresh (NodeRecord record) { // if the hostname of this node changed, kill our existing client and connect anew - if (!record.hostName.equals(_record.hostName) && _client.isActive()) { + String region = _peermgr.getRegion(); + String hostName = record.getPeerHostName(region); + if (!hostName.equals(_record.getPeerHostName(region)) && _client.isActive()) { _client.logoff(false); } @@ -149,7 +151,7 @@ public class PeerNode // otherwise configure our client with the right bits and logon _client.setCredentials(_peermgr.createCreds()); - _client.setServer(_record.hostName, new int[] { _record.port }); + _client.setServer(hostName, new int[] { _record.port }); _client.logon(); _lastConnectStamp = System.currentTimeMillis(); } 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 765852065..b02600af2 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 @@ -23,6 +23,8 @@ package com.threerings.presents.peer.server.persist; import java.sql.Timestamp; +import com.google.common.base.Objects; + import com.samskivert.util.StringUtil; import com.samskivert.depot.Key; @@ -43,6 +45,7 @@ public class NodeRecord extends PersistentRecord public static final ColumnExp NODE_NAME = colexp(_R, "nodeName"); public static final ColumnExp HOST_NAME = colexp(_R, "hostName"); public static final ColumnExp PUBLIC_HOST_NAME = colexp(_R, "publicHostName"); + public static final ColumnExp REGION = colexp(_R, "region"); 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"); @@ -50,7 +53,7 @@ public class NodeRecord extends PersistentRecord /** 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 = 2; + public static final int SCHEMA_VERSION = 3; /** The unique name assigned to this node. */ @Id @@ -65,6 +68,11 @@ public class NodeRecord extends PersistentRecord @Column(name="PUBLIC_HOST_NAME", length=64) public String publicHostName; + /** The region in which the node exists. Nodes in different regions must connect through the + * public host name. */ + @Column(name="REGION", length=64, nullable=true) + public String region; + /** The port on which to connect to this node. */ @Column(name="PORT") public int port; @@ -83,11 +91,13 @@ public class NodeRecord extends PersistentRecord } /** Creates a record for the specified node. */ - public NodeRecord (String nodeName, String hostName, String publicHostName, int port) + public NodeRecord ( + String nodeName, String hostName, String publicHostName, String region, int port) { this.nodeName = nodeName; this.hostName = hostName; this.publicHostName = publicHostName; + this.region = region; this.port = port; } @@ -97,6 +107,14 @@ public class NodeRecord extends PersistentRecord this.nodeName = nodeName; } + /** + * Returns the host name to which peers in the specified region should connect. + */ + public String getPeerHostName (String region) + { + return Objects.equal(this.region, region) ? hostName : publicHostName; + } + @Override public String toString () {