/// <summary> /// Creates ServerNodes list from _settings. /// </summary> private void CreateServerNodes() { foreach (var server in _settings.Servers) { ServerNodes.Add(server.Name, new NGRIDServerNode(server.Name)); } }
/// <summary> /// Gets adjacent nodes from settings and joins servers in ServerNodes. /// </summary> private void JoinNodes() { //Gets adjacents of all nodes var adjacentsOfServers = new SortedList <string, string>(); foreach (var server in _settings.Servers) { adjacentsOfServers.Add(server.Name, server.Adjacents); } //Join adjacents of all nodes foreach (var serverName in adjacentsOfServers.Keys) { //Create adjacent list ServerNodes[serverName].Adjacents = new SortedList <string, NGRIDServerNode>(); //Get adjacent names var adjacents = adjacentsOfServers[serverName].Split(','); //Add nodes as adjacent foreach (var adjacent in adjacents) { var trimmedAdjacentName = adjacent.Trim(); if (string.IsNullOrEmpty(trimmedAdjacentName)) { continue; } if (!ServerNodes.ContainsKey(trimmedAdjacentName)) { throw new NGRIDException("Adjacent server (" + trimmedAdjacentName + ") of server (" + serverName + ") can not be found in servers list."); } ServerNodes[serverName].Adjacents.Add(trimmedAdjacentName, ServerNodes[trimmedAdjacentName]); } } }
/// <summary> /// Sets ThisServerNode field according to _settings and ServerNodes /// </summary> private void SetCurrentServer() { if (ServerNodes.ContainsKey(_settings.ThisServerName)) { ThisServerNode = ServerNodes[_settings.ThisServerName]; } else { throw new NGRIDException("Current server is not defined in settings file."); } }
public List <ServerNode> GetActiveServerNodes(ServerNodes serverNodes) { IList <Address> list = _heartbeatReporter.Keys.ToList(); List <ServerNode> activeNodes = new List <ServerNode>(); foreach (var node in list) { activeNodes.Add(serverNodes.GetServerNode(node.IpAddress.ToString())); } return(activeNodes); }
/// <summary> /// Sets ThisServerNode field according to _settings and ServerNodes /// </summary> private void SetCurrentServer() { if (ServerNodes.ContainsKey(_settings.ThisServerName)) { ThisServerNode = ServerNodes[_settings.ThisServerName]; } //else //{ // throw new MDSException("Current server is not defined in settings file."); //} }
internal int GetHighestNodePriority(IList <Address> nodes, IList <string> maxOplogAddress) { LoggerManager.Instance.SetThreadContext(new LoggerContext() { ShardName = _context.LocalShardName != null ? _context.LocalShardName : "", DatabaseName = "" }); ShardConfiguration sConfig = null; if (_clusterConfigMgr != null) { sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName); } if (sConfig == null || sConfig.Servers == null) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled) { LoggerManager.Instance.ShardLogger.Warn("ElectionManager.GetHeighestNodePriority() ", "The shard (or the nodes of the shard) " + _context.LocalShardName + " does not exist in the configuration."); } return(0); } ServerNodes staticNodes = sConfig.Servers; int maxPriority = Int32.MaxValue; if (nodes != null) { foreach (Address node in nodes) { ServerNode serverNode = staticNodes.GetServerNode(node.IpAddress.ToString()); if (serverNode != null) { int thisPriority = serverNode.Priority; if ((thisPriority < maxPriority) && maxOplogAddress.Contains(serverNode.Name)) { maxPriority = thisPriority; } } } return(maxPriority); } else { throw new Exception("Membership is null."); } }
private string PickOneServer() { if (string.IsNullOrEmpty(ServerNodes)) { throw new ArgumentNullException("ServerNodes"); } var servers = ServerNodes.Split(','); if (servers.Length == 1) { return(servers[0]); } var index = new Random().Next(0, servers.Length); return(servers[index]); }
private void FillAssignNodes() { DataTable NodesDataTable = new DataTable(); NodesDataTable = VSWebBL.SecurityBL.NodesBL.Ins.GetAllData(); DataRow row = NodesDataTable.NewRow(); row["ID"] = "-1"; row["Name"] = ""; NodesDataTable.Rows.InsertAt(row, 0); if (NodesDataTable.Rows.Count > 0) { ServerNodes.DataSource = NodesDataTable; ServerNodes.TextField = "Name"; ServerNodes.ValueField = "ID"; ServerNodes.DataBind(); ServerNodes.Items[0].Selected = true; } }
public void TriggerElectionMechanism(Activity activity, Server server, LocalShardHeartbeatReporting heartbeatReport, Membership existingMembership) { LoggerManager.Instance.SetThreadContext(new LoggerContext() { ShardName = _context.LocalShardName != null ? _context.LocalShardName : "", DatabaseName = "" }); if (existingMembership == null) { existingMembership = new Membership(); } ShardConfiguration sConfig = null; //Get the shard configuration if (_clusterConfigMgr != null) { sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName); } IList <Address> activeNodes = null; MembershipChangeArgs args = new MembershipChangeArgs(); ServerNodes staticServerNodes = null; if (sConfig == null || sConfig.Servers == null) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled) { LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TiggerElectionMechanism() ", "The shard " + _context.LocalShardName + " does not exist in the configuration."); } return; } staticServerNodes = sConfig.Servers; ElectionResult result = null; if (heartbeatReport != null) { activeNodes = heartbeatReport.GetReportTable.Keys.ToList(); } Address activityNode = null; if (server == null) { activityNode = _context.LocalAddress; } else { activityNode = server.Address; } switch (activity) { case Activity.NodeJoining: if (server == null) { return; } //On node join, we need to get membership from the config server for the first time. Membership csMembership = _context.ConfigurationSession.GetMembershipInfo(_context.ClusterName, _context.LocalShardName); ServerNode joiningNode = sConfig.Servers.GetServerNode(server.Address.IpAddress.ToString()); // If the added node is configured while the cluster is up and running, do the following. if (joiningNode == null) { if (_clusterConfigMgr != null) { _clusterConfigMgr.UpdateClusterConfiguration(); sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName); } if (sConfig == null) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled) { LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "The shard " + _context.LocalShardName + " does not exist in the configuration."); } return; } joiningNode = sConfig.Servers.GetServerNode(server.Address.IpAddress.ToString()); } if (joiningNode == null) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled) { LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "The node " + server.Address + " is not part of the configuration."); } return; } if (existingMembership == null || existingMembership.Servers == null || !existingMembership.Servers.Contains(joiningNode)) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled) { LoggerManager.Instance.ShardLogger.Debug("ElectBasedMemSt.TriggerElectMech", "Node joining activity triggered for " + activityNode); } } bool thisNodeIsPrimary = false; OperationId lastOpId = null; if (heartbeatReport != null && heartbeatReport.GetReportTable.ContainsKey(server.Address)) { args.ServerName = _context.LocalAddress; args.ElectionId = null; args.ChangeType = MembershipChangeArgs.MembershipChangeType.NodeJoined; if (server.Address.Equals(_context.LocalAddress)) { _context.ConfigurationSession.ReportNodeJoining(_context.ClusterName, _context.LocalShardName, sConfig.Servers.GetServerNode(_context.LocalAddress.IpAddress.ToString())); if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", server.Address + " reported its joining to the config server. "); } //if the primary is not null and the channel is not disconnected, it can be set here. if ((existingMembership == null || existingMembership.Primary == null) && csMembership.Primary != null && _shard.ActiveChannelsList.Contains(new Server(new Address(csMembership.Primary.Name, sConfig.Port), Status.Initializing)) && ObeysMajorityRule(_shard.ActiveChannelsList.Count, sConfig.Servers.Nodes.Count)) { args.ServerName = new Address(csMembership.Primary.Name, sConfig.Port); args.ElectionId = csMembership.ElectionId; args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimarySet; //if the node which was lost comes back up before the CS or the nodes can declare it dead, //it should resume its status as a primary. There should be no need for an election in this case. if (args.ServerName.Equals(_context.LocalAddress)) { thisNodeIsPrimary = true; } } } if (thisNodeIsPrimary) { if (csMembership.ElectionId != null && LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "election_id: " + csMembership.ElectionId.Id + " election time :" + csMembership.ElectionId.ElectionTime); } if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "I am already declared primary"); } lastOpId = LastOperationId; ChangeMembershipShardwide(args); } else { ((LocalShard)_shard).OnMembershipChanged(args); } if (server.Address.Equals(_context.LocalAddress)) { ServerNode sNode = sConfig.Servers.GetServerNode(_context.LocalAddress.IpAddress.ToString()); if (sNode == null) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled) { LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "The node " + sNode.Name + " does not exist in the configuration."); } return; } _context.ConfigurationSession.ReportHeartbeat(_context.ClusterName, _context.LocalShardName, sNode, existingMembership, lastOpId); } } else { if (existingMembership.Primary != null && existingMembership.Primary.Name.Equals(server.Address.IpAddress.ToString())) { if (sConfig.Servers == null || sConfig.Servers.Nodes == null || !ObeysMajorityRule(activeNodes.Count, sConfig.Servers.Nodes.Count)) { _context.ConfigurationSession.SetNodeStatus(_context.ClusterName, _context.LocalShardName, existingMembership.Primary, NodeRole.None); args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted; args.ServerName = _context.LocalAddress; ChangeMembershipShardwide(args); if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", " Node addition activity occured. Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted."); } return; } } } break; case Activity.NodeLeaving: if (server == null) { return; } bool hasMajority = ObeysMajorityRule(activeNodes.Count, staticServerNodes.Nodes.Count); args.ServerName = server.Address; args.ChangeType = MembershipChangeArgs.MembershipChangeType.NodeLeft; _clusterConfigMgr.UpdateClusterConfiguration(); if (existingMembership.Primary != null) { // if the existing primary is actually the node lost, we need to update the configuration. if (existingMembership.Primary.Name == server.Address.IpAddress.ToString()) { //if Primary leaves, it should be updated locally. args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryLost; if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled) { LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", "Node leaving activity triggered for " + server.Address + " . Primary lost."); } } else if (existingMembership.Primary.Name == _context.LocalAddress.IpAddress.ToString()) // if the existing primary is the local node, we need to check for possible demotion of the current primary. { if (!hasMajority) { _context.ConfigurationSession.SetNodeStatus(_context.ClusterName, _context.LocalShardName, existingMembership.Primary, NodeRole.None); args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted; args.ServerName = _context.LocalAddress; ChangeMembershipShardwide(args); if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled) { LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", " Node leaving activity occurred. Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted."); } return; } } } ((LocalShard)_shard).OnMembershipChanged(args); break; case Activity.GeneralElectionsTriggered: case Activity.TakeoverElectionsTriggered: // this is where the actual election mechanism takes place. //Step 1: if no node in the heartbeat table has a primary and there is no primary in the local node's membership, we proceed forward. //Else if there is a primary but this looks like the takeover election mechanism, we proceed along as well. if ((activity.Equals(Activity.GeneralElectionsTriggered) && !heartbeatReport.PrimaryExists() && existingMembership.Primary == null) || (activity.Equals(Activity.TakeoverElectionsTriggered) && heartbeatReport.PrimaryExists())) { //Step 2: we verify that this node has a majority of the shard nodes connected to it. if (activeNodes != null && ObeysMajorityRule(activeNodes.Count, staticServerNodes.Nodes.Count)) { //Step 3: Perform the initial sanity check. (Speculative phase) if (ShouldIInitiateElection(heartbeatReport, activity)) { if (existingMembership != null && existingMembership.Primary != null && activity == Activity.GeneralElectionsTriggered) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "A primary has already been selected for " + _context.LocalShardName + " hence exiting the election mechanism."); } return; } //Step 4: The elections take place in real. (Authoritative Phase) result = HoldElection(heartbeatReport, activity); if (result != null) { if (result.PollingResult == ElectionResult.Result.PrimarySelected) { //if the shard is undergoing the takeover election mechanism, the old primary needs to //be demoted first. bool oldPrimaryDemoted = false; if (activity == Activity.TakeoverElectionsTriggered) { MembershipChangeArgs args2 = new MembershipChangeArgs(); args2.ChangeType = MembershipChangeArgs.MembershipChangeType.ForcefullyDemotePrimary; args2.ServerName = _context.LocalAddress; args2.ElectionId = existingMembership.ElectionId; Message msg = new Message(); msg.Payload = args2; msg.MessageType = MessageType.MembershipOperation; msg.NeedsResponse = true; ShardRequestBase <bool> request = _shard.CreateUnicastRequest <bool>(new Server(new Address(existingMembership.Primary.Name, sConfig.Port), Status.Running), msg); IAsyncResult result2 = request.BeginExecute(); oldPrimaryDemoted = request.EndExecute(result2); } //Submit the result to the CS. if (activity == Activity.GeneralElectionsTriggered || (activity == Activity.TakeoverElectionsTriggered && oldPrimaryDemoted)) { _context.ConfigurationSession.SubmitElectionResult(_context.ClusterName.ToLower(), _context.LocalShardName.ToLower(), result); } if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled) { LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", "Election result submitted for shard " + _context.LocalShardName.ToString()); } _context.ElectionResult = result; args.ServerName = _context.LocalAddress; args.ElectionId = result.ElectionId; args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimarySelected; //Once, the result is submitted, inform the shard nodes. ChangeMembershipShardwide(args); _context.ConfigurationSession.ReportHeartbeat(_context.ClusterName, _context.LocalShardName, result.ElectedPrimary, existingMembership, LastOperationId); } //Finally, end this round of elections. _context.ConfigurationSession.EndElection(_context.ClusterName, _context.LocalShardName, result.ElectionId); } } } } break; case Activity.CSDisconnected: //this is called whenever a node loses connection with the config server. if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled) { LoggerManager.Instance.ShardLogger.Debug("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "Config Server disconnected. "); } //if the number of configured nodes are even and the primary loses connection with the CS, it needs to demote itself. if (existingMembership != null && existingMembership.Primary != null && existingMembership.Primary.Name == _context.LocalAddress.IpAddress.ToString() && staticServerNodes.Nodes.Count % 2 == 0) { if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled) { LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", " Connection of the node " + _context.LocalAddress.ToString() + " with the config server is lost."); } args.ServerName = _context.LocalAddress; args.ElectionId = existingMembership.ElectionId; args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted; ChangeMembershipShardwide(args); if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", " Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted because the primary lost connection with the CS."); } } break; case Activity.ForcefulPrimaryDemotion: if (existingMembership != null && existingMembership.Primary != null && existingMembership.Primary.Name == _context.LocalAddress.IpAddress.ToString()) { _context.ConfigurationSession.SetNodeStatus(_context.ClusterName, _context.LocalShardName, existingMembership.Primary, NodeRole.None); args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted; args.ServerName = _context.LocalAddress; if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled) { LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted in order to complete the take over election mechanism. "); } ((LocalShard)_shard).OnMembershipChanged(args); } break; } }
public ActionResult <Task> Update([FromBody] ServerNode model) => ServerNodes.Update(model);
public ActionResult <List <ServerNode> > FindAll() => ServerNodes.FindAll();
public ActionResult <ServerNode> FindById([FromQuery] string id) => ServerNodes.FindById(id);
public ActionResult <Task> DeleteClusterNode([FromBody] ServerNode model) => ServerNodes.DeleteServerNode(model);
public ActionResult <Task> CreateCluster([FromBody] ServerNode model) => ServerNodes.AddServerNode(model);