/** * Creates a new Link, or retrieves an existing one, from a NodeAddress * * @param addr * The NodeAddress of the Node to connect to * @return A new Link connected to the node at the given NodeAddress * @//throws JCSPNetworkException * Thrown if anything goes wrong during the connection */ public static Link getLink(NodeAddress addr) ////throws JCSPNetworkException { // Log start of creation Node.log.log(typeof(LinkFactory), "Trying to get link to " + addr.toString()); // Create Link from address Link toReturn = addr.createLink(); Console.WriteLine("Finished creating link NodeID " + toReturn.remoteID); // Now attempt to connect the Link. If connect fails, then the opposite node already has a connection to us. // This may occur during connection if the opposite end registered its Link prior to us doing so. In such // a circumstance, the Link should eventually appear in the LinkManager. if (!toReturn.connect()) { // Connect failed. Get NodeID of remote Node (this will have been set during the connect operation) NodeID remoteID = toReturn.getRemoteNodeID(); // Log failed connect Node.log.log(typeof(LinkFactory), "Failed to connect to " + remoteID.toString()); Console.WriteLine("Failed to connect to " + remoteID.toString()); // Set the Link to return to null toReturn = null; // Loop until the Link is connected. This is a possible weakness. Although it is believed that the // opposite end will eventually connect, we may have a problem if this continually loops. For information, // log every attempt. while (toReturn == null) { try { // Go to sleep for a bit, and give the Link a chance to register Thread.Sleep(100); // Log start of attempt Node.log.log(typeof(LinkFactory), "Attempting to retrieve Link to " + remoteID.toString()); // Retrieve Link from LinkManager toReturn = LinkManager.getInstance().requestLink(remoteID); } catch (ThreadInterruptedException ie) { // Ignore. Should never really happen } } // Return the Link retrieved from the LinkManager return(toReturn); } // Connection succeeded. Register Link with the LinkManager toReturn.registerLink(); // Now start the Link new ProcessManager(toReturn).start(); // Return the Link return(toReturn); }