/// <summary> /// Return first valid node referenced by seed host aliases. In most cases, aliases /// reference a single node. If round robin DNS configuration is used, the seed host /// may have several addresses that reference different nodes in the cluster. /// </summary> public Node SeedNode(Cluster cluster, Host host, Peers peers) { name = null; aliases = null; primaryHost = null; primaryAddress = null; primaryConn = null; sessionToken = null; sessionExpiration = null; features = 0; IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout); Exception exception = null; // Try all addresses because they might point to different nodes. foreach (IPAddress address in addresses) { try { ValidateAddress(cluster, address, host.tlsName, host.port, true); // Only set aliases when they were not set by load balancer detection logic. if (this.aliases == null) { SetAliases(address, host.tlsName, host.port); } Node node = cluster.CreateNode(this, false); if (ValidatePeers(peers, node)) { return(node); } } catch (Exception e) { // Log exception and continue to next alias. if (Log.DebugEnabled()) { Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e)); } if (exception == null) { exception = e; } } } // Fallback signifies node exists, but is suspect. // Return null so other seeds can be tried. if (fallback != null) { return(null); } // Exception can't be null here because Connection.GetHostAddresses() // will throw exception if aliases length is zero. throw exception; }
private bool PrepareFriend(Host host, Peers peers) { try { NodeValidator nv = new NodeValidator(); nv.ValidateNode(cluster, host); // Check for duplicate nodes in nodes slated to be added. Node node; if (peers.nodes.TryGetValue(nv.name, out node)) { // Duplicate node name found. This usually occurs when the server // services list contains both internal and external IP addresses // for the same node. nv.primaryConn.Close(); peers.hosts.Add(host); node.aliases.Add(host); return(true); } // Check for duplicate nodes in cluster. if (cluster.nodesMap.TryGetValue(nv.name, out node)) { nv.primaryConn.Close(); peers.hosts.Add(host); node.aliases.Add(host); node.referenceCount++; cluster.aliases[host] = node; return(true); } node = cluster.CreateNode(nv); peers.hosts.Add(host); peers.nodes[nv.name] = node; return(true); } catch (Exception e) { if (Log.WarnEnabled()) { Log.Warn("Add node " + host + " failed: " + Util.GetErrorMessage(e)); } return(false); } }
/// <summary> /// Add node(s) referenced by seed host aliases. In most cases, aliases reference /// a single node. If round robin DNS configuration is used, the seed host may have /// several addresses that reference different nodes in the cluster. /// </summary> public void SeedNodes(Cluster cluster, Host host, Dictionary <string, Node> nodesToAdd) { IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout); Exception exception = null; bool found = false; // Try all addresses because they might point to different nodes. foreach (IPAddress address in addresses) { try { ValidateAddress(cluster, address, host.tlsName, host.port, true); found = true; if (!nodesToAdd.ContainsKey(name)) { // New node found. // Only set aliases when they were not set by load balancer detection logic. if (this.aliases == null) { SetAliases(addresses, host.tlsName, host.port); } Node node = cluster.CreateNode(this); nodesToAdd[name] = node; } else { // Node already referenced. Close connection. primaryConn.Close(); } } catch (Exception e) { // Log and continue to next address. if (Log.DebugEnabled()) { Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e)); } if (exception == null) { exception = e; } } } if (!found) { // Exception can't be null here because Connection.GetHostAddresses() // will throw exception if aliases length is zero. throw exception; } }
/// <summary> /// Add node(s) referenced by seed host aliases. In most cases, aliases reference /// a single node. If round robin DNS configuration is used, the seed host may have /// several aliases that reference different nodes in the cluster. /// </summary> public void SeedNodes(Cluster cluster, Host host, List <Node> list) { IPAddress[] addresses = SetAliases(cluster, host); Exception exception = null; bool found = false; foreach (IPAddress address in addresses) { try { ValidateAlias(cluster, address, host.port); found = true; if (!FindNodeName(list, name)) { // New node found. Node node = cluster.CreateNode(this); cluster.AddAliases(node); list.Add(node); } else { // Node already referenced. Close connection. conn.Close(); } } catch (Exception e) { // Log and continue to next address. if (Log.DebugEnabled()) { Log.Debug("Alias " + address + " failed: " + Util.GetErrorMessage(e)); } if (exception == null) { exception = e; } } } if (!found) { // Exception can't be null here because SetAliases()/Connection.GetHostAddresses() // will throw exception if aliases length is zero. throw exception; } }
/// <summary> /// Add node(s) referenced by seed host aliases. In most cases, aliases reference /// a single node. If round robin DNS configuration is used, the seed host may have /// several aliases that reference different nodes in the cluster. /// </summary> public void SeedNodes(Cluster cluster, Host host, List<Node> list) { IPAddress[] addresses = SetAliases(cluster, host); Exception exception = null; bool found = false; foreach (IPAddress address in addresses) { try { ValidateAlias(cluster, address, host.port); found = true; if (!FindNodeName(list, name)) { // New node found. Node node = cluster.CreateNode(this); cluster.AddAliases(node); list.Add(node); } else { // Node already referenced. Close connection. conn.Close(); } } catch (Exception e) { // Log and continue to next address. if (Log.DebugEnabled()) { Log.Debug("Alias " + address + " failed: " + Util.GetErrorMessage(e)); } if (exception == null) { exception = e; } } } if (!found) { // Exception can't be null here because SetAliases()/Connection.GetHostAddresses() // will throw exception if aliases length is zero. throw exception; } }
/// <summary> /// Return first valid node referenced by seed host aliases. In most cases, aliases /// reference a single node. If round robin DNS configuration is used, the seed host /// may have several addresses that reference different nodes in the cluster. /// </summary> public Node SeedNode(Cluster cluster, Host host) { IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout); Exception exception = null; // Try all addresses because they might point to different nodes. foreach (IPAddress address in addresses) { try { ValidateAddress(cluster, address, host.tlsName, host.port, true); // Only set aliases when they were not set by load balancer detection logic. if (this.aliases == null) { SetAliases(address, host.tlsName, host.port); } return(cluster.CreateNode(this)); } catch (Exception e) { // Log exception and continue to next alias. if (Log.DebugEnabled()) { Log.Debug("Address " + address + ' ' + host.port + " failed: " + Util.GetErrorMessage(e)); } if (exception == null) { exception = e; } } } // Exception can't be null here because Connection.GetHostAddresses() // will throw exception if aliases length is zero. throw exception; }
protected internal void RefreshPeers(Peers peers) { // Do not refresh peers when node connection has already failed during this cluster tend iteration. if (failures > 0 || !active) { return; } try { if (Log.DebugEnabled()) { Log.Debug("Update peers for node " + this); } PeerParser parser = new PeerParser(cluster, tendConnection, peers.peers); peersCount = peers.peers.Count; bool peersValidated = true; foreach (Peer peer in peers.peers) { if (FindPeerNode(cluster, peers, peer.nodeName)) { // Node already exists. Do not even try to connect to hosts. continue; } bool nodeValidated = false; // Find first host that connects. foreach (Host host in peer.hosts) { try { // Attempt connection to host. NodeValidator nv = new NodeValidator(); nv.ValidateNode(cluster, host); if (!peer.nodeName.Equals(nv.name)) { // Must look for new node name in the unlikely event that node names do not agree. if (Log.WarnEnabled()) { Log.Warn("Peer node " + peer.nodeName + " is different than actual node " + nv.name + " for host " + host); } if (FindPeerNode(cluster, peers, nv.name)) { // Node already exists. Do not even try to connect to hosts. nv.primaryConn.Close(); nodeValidated = true; break; } } // Create new node. Node node = cluster.CreateNode(nv, true); peers.nodes[nv.name] = node; nodeValidated = true; break; } catch (Exception e) { if (Log.WarnEnabled()) { Log.Warn("Add node " + host + " failed: " + Util.GetErrorMessage(e)); } } } if (!nodeValidated) { peersValidated = false; } } // Only set new peers generation if all referenced peers are added to the cluster. if (peersValidated) { peersGeneration = parser.generation; } peers.refreshCount++; } catch (Exception e) { RefreshFailed(e); } }