Exemplo n.º 1
0
        /// <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;
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 7
0
        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);
            }
        }