Widening.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4524 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -51,17 +51,16 @@ import com.threerings.presents.peer.server.persist.NodeRepository;
|
|||||||
import static com.threerings.presents.Log.log;
|
import static com.threerings.presents.Log.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages connections to the other nodes in a Presents server cluster. Each
|
* Manages connections to the other nodes in a Presents server cluster. Each server maintains a
|
||||||
* server maintains a client connection to the other servers and subscribes to
|
* client connection to the other servers and subscribes to the {@link NodeObject} of all peer
|
||||||
* the {@link NodeObject} of all peer servers and uses those objects to
|
* servers and uses those objects to communicate cross-node information.
|
||||||
* communicate cross-node information.
|
|
||||||
*/
|
*/
|
||||||
public class PeerManager
|
public class PeerManager
|
||||||
implements ClientManager.ClientObserver
|
implements ClientManager.ClientObserver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Creates a peer manager which will create a {@link NodeRepository} which
|
* Creates a peer manager which will create a {@link NodeRepository} which will be used to
|
||||||
* will be used to publish our existence and discover the other nodes.
|
* publish our existence and discover the other nodes.
|
||||||
*/
|
*/
|
||||||
public PeerManager (ConnectionProvider conprov, Invoker invoker)
|
public PeerManager (ConnectionProvider conprov, Invoker invoker)
|
||||||
throws PersistenceException
|
throws PersistenceException
|
||||||
@@ -79,24 +78,21 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes this peer manager and initiates the process of connecting to
|
* Initializes this peer manager and initiates the process of connecting to its peer
|
||||||
* its peer nodes. This will also reconfigure the ConnectionManager and
|
* nodes. This will also reconfigure the ConnectionManager and ClientManager with peer related
|
||||||
* ClientManager with peer related bits, so this should not be called until
|
* bits, so this should not be called until <em>after</em> the main server has set up its
|
||||||
* <em>after</em> the main server has set up its client factory and
|
* client factory and authenticator.
|
||||||
* authenticator.
|
|
||||||
*
|
*
|
||||||
* @param nodeName this node's unique name.
|
* @param nodeName this node's unique name.
|
||||||
* @param sharedSecret a shared secret used to allow the peers to
|
* @param sharedSecret a shared secret used to allow the peers to authenticate with one
|
||||||
* authenticate with one another.
|
* another.
|
||||||
* @param hostName the DNS name of the server running this node.
|
* @param hostName the DNS name of the server running this node.
|
||||||
* @param publicHostName if non-null, a separate public DNS hostname by
|
* @param publicHostName if non-null, a separate public DNS hostname by which the node is to be
|
||||||
* which the node is to be known to normal clients (we may want inter-peer
|
* known to normal clients (we may want inter-peer communication to take place over a different
|
||||||
* communication to take place over a different network than the
|
* network than the communication between real clients and the various peer servers).
|
||||||
* communication between real clients and the various peer servers).
|
|
||||||
* @param port the port on which other nodes should connect to us.
|
* @param port the port on which other nodes should connect to us.
|
||||||
* @param conprov used to obtain our JDBC connections.
|
* @param conprov used to obtain our JDBC connections.
|
||||||
* @param invoker we will perform all database operations on the supplied
|
* @param invoker we will perform all database operations on the supplied invoker thread.
|
||||||
* invoker thread.
|
|
||||||
*/
|
*/
|
||||||
public void init (String nodeName, String sharedSecret, String hostName,
|
public void init (String nodeName, String sharedSecret, String hostName,
|
||||||
String publicHostName, int port)
|
String publicHostName, int port)
|
||||||
@@ -109,11 +105,9 @@ public class PeerManager
|
|||||||
|
|
||||||
// wire ourselves into the server
|
// wire ourselves into the server
|
||||||
PresentsServer.conmgr.setAuthenticator(
|
PresentsServer.conmgr.setAuthenticator(
|
||||||
new PeerAuthenticator(
|
new PeerAuthenticator(this, PresentsServer.conmgr.getAuthenticator()));
|
||||||
this, PresentsServer.conmgr.getAuthenticator()));
|
|
||||||
PresentsServer.clmgr.setClientFactory(
|
PresentsServer.clmgr.setClientFactory(
|
||||||
new PeerClientFactory(
|
new PeerClientFactory(this, PresentsServer.clmgr.getClientFactory()));
|
||||||
this, PresentsServer.clmgr.getClientFactory()));
|
|
||||||
|
|
||||||
// create our node object
|
// create our node object
|
||||||
_nodeobj = PresentsServer.omgr.registerObject(createNodeObject());
|
_nodeobj = PresentsServer.omgr.registerObject(createNodeObject());
|
||||||
@@ -121,13 +115,12 @@ public class PeerManager
|
|||||||
// register ourselves with the node table
|
// register ourselves with the node table
|
||||||
_invoker.postUnit(new Invoker.Unit() {
|
_invoker.postUnit(new Invoker.Unit() {
|
||||||
public boolean invoke () {
|
public boolean invoke () {
|
||||||
NodeRecord record = new NodeRecord(
|
NodeRecord record = new NodeRecord(_nodeName, _hostName, _publicHostName, _port);
|
||||||
_nodeName, _hostName, _publicHostName, _port);
|
|
||||||
try {
|
try {
|
||||||
_noderepo.updateNode(record);
|
_noderepo.updateNode(record);
|
||||||
} catch (PersistenceException pe) {
|
} catch (PersistenceException pe) {
|
||||||
log.warning("Failed to register node record " +
|
log.warning("Failed to register node record [rec=" + record +
|
||||||
"[rec=" + record + ", error=" + pe + "].");
|
", error=" + pe + "].");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -136,8 +129,8 @@ public class PeerManager
|
|||||||
// register ourselves as a client observer
|
// register ourselves as a client observer
|
||||||
PresentsServer.clmgr.addClientObserver(this);
|
PresentsServer.clmgr.addClientObserver(this);
|
||||||
|
|
||||||
// and start our peer refresh interval (this need not use a runqueue as
|
// and start our peer refresh interval (this need not use a runqueue as all it will do is
|
||||||
// all it will do is post an invoker unit)
|
// post an invoker unit)
|
||||||
new Interval() {
|
new Interval() {
|
||||||
public void expired () {
|
public void expired () {
|
||||||
refreshPeers();
|
refreshPeers();
|
||||||
@@ -149,9 +142,8 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this when the server is shutting down to give this node a chance to
|
* Call this when the server is shutting down to give this node a chance to cleanly logoff from
|
||||||
* cleanly logoff from its peers and remove its record from the nodes
|
* its peers and remove its record from the nodes table.
|
||||||
* table.
|
|
||||||
*/
|
*/
|
||||||
public void shutdown ()
|
public void shutdown ()
|
||||||
{
|
{
|
||||||
@@ -169,8 +161,8 @@ public class PeerManager
|
|||||||
*/
|
*/
|
||||||
public boolean isAuthenticPeer (PeerCreds creds)
|
public boolean isAuthenticPeer (PeerCreds creds)
|
||||||
{
|
{
|
||||||
return PeerCreds.createPassword(
|
return PeerCreds.createPassword(creds.getNodeName(), _sharedSecret).equals(
|
||||||
creds.getNodeName(), _sharedSecret).equals(creds.getPassword());
|
creds.getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface ClientManager.ClientObserver
|
// documentation inherited from interface ClientManager.ClientObserver
|
||||||
@@ -187,10 +179,8 @@ public class PeerManager
|
|||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (_nodeobj.clients.contains(clinfo)) {
|
if (_nodeobj.clients.contains(clinfo)) {
|
||||||
log.warning("Received clientSessionDidStart() for already " +
|
log.warning("Received clientSessionDidStart() for already registered client!? " +
|
||||||
"registered client!? " +
|
"[old=" + _nodeobj.clients.get(clinfo.getKey()) + ", new=" + clinfo + "].");
|
||||||
"[old=" + _nodeobj.clients.get(clinfo.getKey()) +
|
|
||||||
", new=" + clinfo + "].");
|
|
||||||
// go ahead and update the record
|
// go ahead and update the record
|
||||||
_nodeobj.updateClients(clinfo);
|
_nodeobj.updateClients(clinfo);
|
||||||
} else {
|
} else {
|
||||||
@@ -206,9 +196,9 @@ public class PeerManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we scan through the list instead of relying on ClientInfo.getKey()
|
// we scan through the list instead of relying on ClientInfo.getKey() because we want
|
||||||
// because we want derived classes to be able to override that for
|
// derived classes to be able to override that for lookups that happen way more frequently
|
||||||
// lookups that happen way more frequently than logging off
|
// than logging off
|
||||||
Name username = client.getCredentials().getUsername();
|
Name username = client.getCredentials().getUsername();
|
||||||
for (ClientInfo clinfo : _nodeobj.clients) {
|
for (ClientInfo clinfo : _nodeobj.clients) {
|
||||||
if (clinfo.username.equals(username)) {
|
if (clinfo.username.equals(username)) {
|
||||||
@@ -216,8 +206,7 @@ public class PeerManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.warning("Session ended for unregistered client " +
|
log.warning("Session ended for unregistered client [who=" + username + "].");
|
||||||
"[who=" + username + "].");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,8 +217,8 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the list of peer nodes from our table and refreshes each with a
|
* Reloads the list of peer nodes from our table and refreshes each with a call to {@link
|
||||||
* call to {@link #refreshPeer}.
|
* #refreshPeer}.
|
||||||
*/
|
*/
|
||||||
protected void refreshPeers ()
|
protected void refreshPeers ()
|
||||||
{
|
{
|
||||||
@@ -253,8 +242,7 @@ public class PeerManager
|
|||||||
try {
|
try {
|
||||||
refreshPeer(record);
|
refreshPeer(record);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.log(Level.WARNING, "Failure refreshing peer " +
|
log.log(Level.WARNING, "Failure refreshing peer " + record + ".", e);
|
||||||
record + ".", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,8 +251,8 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that we have a connection to the specified node if it has
|
* Ensures that we have a connection to the specified node if it has checked in since we last
|
||||||
* checked in since we last failed to connect.
|
* failed to connect.
|
||||||
*/
|
*/
|
||||||
protected void refreshPeer (NodeRecord record)
|
protected void refreshPeer (NodeRecord record)
|
||||||
{
|
{
|
||||||
@@ -276,8 +264,8 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the appropriate derived class of {@link NodeObject} which will
|
* Creates the appropriate derived class of {@link NodeObject} which will be registered with
|
||||||
* be registered with the distributed object system.
|
* the distributed object system.
|
||||||
*/
|
*/
|
||||||
protected NodeObject createNodeObject ()
|
protected NodeObject createNodeObject ()
|
||||||
{
|
{
|
||||||
@@ -285,8 +273,8 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link ClientInfo} record which will subsequently be
|
* Creates a {@link ClientInfo} record which will subsequently be initialized by a call to
|
||||||
* initialized by a call to {@link #initClientInfo}.
|
* {@link #initClientInfo}.
|
||||||
*/
|
*/
|
||||||
protected ClientInfo createClientInfo ()
|
protected ClientInfo createClientInfo ()
|
||||||
{
|
{
|
||||||
@@ -302,8 +290,7 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link PeerNode} to manage our connection to the specified
|
* Creates a {@link PeerNode} to manage our connection to the specified peer.
|
||||||
* peer.
|
|
||||||
*/
|
*/
|
||||||
protected PeerNode createPeerNode (NodeRecord record)
|
protected PeerNode createPeerNode (NodeRecord record)
|
||||||
{
|
{
|
||||||
@@ -333,8 +320,8 @@ public class PeerManager
|
|||||||
|
|
||||||
public void refresh (NodeRecord record)
|
public void refresh (NodeRecord record)
|
||||||
{
|
{
|
||||||
// if the hostname of this node changed, kill our existing client
|
// if the hostname of this node changed, kill our existing client connection and
|
||||||
// connection and connect anew
|
// connect anew
|
||||||
if (!record.hostName.equals(_record.hostName) &&
|
if (!record.hostName.equals(_record.hostName) &&
|
||||||
_client.isActive()) {
|
_client.isActive()) {
|
||||||
_client.logoff(false);
|
_client.logoff(false);
|
||||||
@@ -345,8 +332,8 @@ public class PeerManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if our client hasn't updated its record since we last tried to
|
// if our client hasn't updated its record since we last tried to logon, then just
|
||||||
// logon, then just chill
|
// chill
|
||||||
if (_lastConnectStamp > record.lastUpdated.getTime()) {
|
if (_lastConnectStamp > record.lastUpdated.getTime()) {
|
||||||
log.fine("Not reconnecting to stale client [record=" + _record +
|
log.fine("Not reconnecting to stale client [record=" + _record +
|
||||||
", lastTry=" + new Date(_lastConnectStamp) + "].");
|
", lastTry=" + new Date(_lastConnectStamp) + "].");
|
||||||
@@ -354,8 +341,7 @@ public class PeerManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// otherwise configure our client with the right bits and logon
|
// otherwise configure our client with the right bits and logon
|
||||||
_client.setCredentials(
|
_client.setCredentials(new PeerCreds(_record.nodeName, _sharedSecret));
|
||||||
new PeerCreds(_record.nodeName, _sharedSecret));
|
|
||||||
_client.setServer(record.hostName, new int[] { _record.port });
|
_client.setServer(record.hostName, new int[] { _record.port });
|
||||||
_client.logon();
|
_client.logon();
|
||||||
_lastConnectStamp = System.currentTimeMillis();
|
_lastConnectStamp = System.currentTimeMillis();
|
||||||
@@ -388,8 +374,7 @@ public class PeerManager
|
|||||||
log.info("Connected to peer " + _record + ".");
|
log.info("Connected to peer " + _record + ".");
|
||||||
|
|
||||||
// subscribe to this peer's node object
|
// subscribe to this peer's node object
|
||||||
PeerBootstrapData pdata = (PeerBootstrapData)
|
PeerBootstrapData pdata = (PeerBootstrapData)client.getBootstrapData();
|
||||||
client.getBootstrapData();
|
|
||||||
client.getDObjectManager().subscribeToObject(pdata.nodeOid, this);
|
client.getDObjectManager().subscribeToObject(pdata.nodeOid, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user