public Cluster(ClientPolicy policy, Host[] hosts) { this.seeds = hosts; if (policy.user != null && policy.user.Length > 0) { this.user = ByteUtil.StringToUtf8(policy.user); string pass = policy.password; if (pass == null) { pass = ""; } if (! (pass.Length == 60 && pass.StartsWith("$2a$"))) { pass = AdminCommand.HashPassword(pass); } this.password = ByteUtil.StringToUtf8(pass); } connectionQueueSize = policy.maxThreads + 1; // Add one connection for tend thread. connectionTimeout = policy.timeout; maxSocketIdleMillis = 1000 * ((policy.maxSocketIdle <= MaxSocketIdleSecondLimit) ? policy.maxSocketIdle : MaxSocketIdleSecondLimit); tendInterval = policy.tendInterval; ipMap = policy.ipMap; requestProleReplicas = policy.requestProleReplicas; aliases = new Dictionary<Host, Node>(); nodes = new Node[0]; partitionMap = new Dictionary<string, Node[][]>(); }
/// <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> /// Initialize server node with connection parameters. /// </summary> /// <param name="cluster">collection of active server nodes</param> /// <param name="nv">connection parameters</param> public Node(Cluster cluster, NodeValidator nv) { this.cluster = cluster; this.name = nv.name; this.aliases = nv.aliases; this.address = nv.address; this.hasDouble = nv.hasDouble; this.hasBatchIndex = nv.hasBatchIndex; this.hasReplicasAll = nv.hasReplicasAll; // Assign host to first IP alias because the server identifies nodes // by IP address (not hostname). this.host = aliases[0]; connectionQueue = new BlockingCollection<Connection>(cluster.connectionQueueSize); }
public AsyncCluster(AsyncClientPolicy policy, Host[] hosts) : base(policy, hosts) { maxCommands = policy.asyncMaxCommands; block = policy.asyncMaxCommandAction == MaxCommandAction.BLOCK; argsQueue = new BlockingCollection<SocketAsyncEventArgs>(maxCommands); for (int i = 0; i < maxCommands; i++) { SocketAsyncEventArgs eventArgs = new SocketAsyncEventArgs(); eventArgs.Completed += AsyncCommand.SocketListener; argsQueue.Add(eventArgs); } bufferPool = new BufferPool(); InitTendThread(policy.failIfNotConnected); }
public NodeValidator(Cluster cluster, Host host) { IPAddress[] addresses = Connection.GetHostAddresses(host.name, DEFAULT_TIMEOUT); aliases = new Host[addresses.Length]; for (int i = 0; i < addresses.Length; i++) { aliases[i] = new Host(addresses[i].ToString(), host.port); } Exception exception = null; for (int i = 0; i < addresses.Length; i++) { try { IPEndPoint address = new IPEndPoint(addresses[i], host.port); Connection conn = new Connection(address, cluster.connectionTimeout); try { if (cluster.user != null) { AdminCommand command = new AdminCommand(); command.Authenticate(conn, cluster.user, cluster.password); } Dictionary<string, string> map = Info.Request(conn, "node", "features"); string nodeName; if (map.TryGetValue("node", out nodeName)) { this.name = nodeName; this.address = address; SetFeatures(map); return; } } finally { conn.Close(); } } catch (Exception e) { // Try next address. if (Log.DebugEnabled()) { Log.Debug("Alias " + addresses[i] + " failed: " + Util.GetErrorMessage(e)); } if (exception == null) { exception = e; } } } if (exception == null) { throw new AerospikeException.Connection("Failed to find addresses for " + host); } throw exception; }
private bool FindSeed(Host search) { foreach (Host seed in seeds) { if (seed.Equals(search)) { return true; } } return false; }
public void AddSeeds(Host[] hosts) { // Use copy on write semantics. Host[] seedArray = new Host[seeds.Length + hosts.Length]; int count = 0; // Add existing seeds. foreach (Host seed in seeds) { seedArray[count++] = seed; } // Add new seeds foreach (Host host in hosts) { if (Log.DebugEnabled()) { Log.Debug("Add seed " + host); } seedArray[count++] = host; } // Replace nodes with copy. seeds = seedArray; }
private bool AddFriends(Dictionary<string, string> infoMap, List<Host> friends) { // Parse the service addresses and add the friends to the list. String command = cluster.useServicesAlternate ? "services-alternate" : "services"; string friendString = infoMap[command]; if (friendString == null || friendString.Length == 0) { // Detect "split cluster" case where this node thinks it's a 1-node cluster. // Unchecked, such a node can dominate the partition map and cause all other // nodes to be dropped. int nodeCount = cluster.Nodes.Length; if (nodeCount > 2) { if (Log.WarnEnabled()) { Log.Warn("Node " + this + " thinks it owns cluster, but client sees " + nodeCount + " nodes."); } return false; } return true; } string[] friendNames = friendString.Split(';'); foreach (string friend in friendNames) { string[] friendInfo = friend.Split(':'); string host = friendInfo[0]; string alternativeHost; if (cluster.ipMap != null && cluster.ipMap.TryGetValue(host, out alternativeHost)) { host = alternativeHost; } int port = Convert.ToInt32(friendInfo[1]); Host alias = new Host(host, port); Node node; if (cluster.aliases.TryGetValue(alias, out node)) { node.referenceCount++; } else { if (!FindAlias(friends, alias)) { friends.Add(alias); } } } return true; }
private static bool FindAlias(List<Host> friends, Host alias) { foreach (Host host in friends) { if (host.Equals(alias)) { return true; } } return false; }
/// <summary> /// Add node alias to list. /// </summary> public void AddAlias(Host aliasToAdd) { // Aliases are only referenced in the cluster tend thread, // so synchronization is not necessary. Host[] tmpAliases = new Host[aliases.Length + 1]; int count = 0; foreach (Host host in aliases) { tmpAliases[count++] = host; } tmpAliases[count] = aliasToAdd; aliases = tmpAliases; }
private IPAddress[] SetAliases(Cluster cluster, Host host) { IPAddress[] addresses = Connection.GetHostAddresses(host.name, cluster.connectionTimeout); aliases = new Host[addresses.Length]; for (int i = 0; i < addresses.Length; i++) { aliases[i] = new Host(addresses[i].ToString(), host.port); } return addresses; }
/// <summary> /// Verify that a host alias references a valid node. /// </summary> public void ValidateNode(Cluster cluster, Host host) { IPAddress[] addresses = SetAliases(cluster, host); Exception exception = null; foreach (IPAddress address in addresses) { try { ValidateAlias(cluster, address, host.port); return; } 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; } } } // Exception can't be null here because SetAliases()/Connection.GetHostAddresses() // will throw exception if aliases length is zero. throw exception; }