Example #1
0
        //When a new shard is added, do the following
        public void OnShardAdded(ShardInfo shard)
        {
            if (shard != null)
            {
                if (shard.Name != context.LocalShardName && _remoteShards != null && !_remoteShards.ContainsKey(shard.Name))
                {
                    if (_clusterConfigMgr != null)
                    {
                        _clusterConfigMgr.UpdateClusterConfiguration();
                        ShardConfiguration sConfig = _clusterConfigMgr.GetShardConfiguration(context.LocalShardName);
                        if (sConfig == null)
                        {
                            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                            {
                                LoggerManager.Instance.ShardLogger.Warn("ClusterManager.OnShardAdded() ", "The shard " + shard.Name + " does not exist in the configuration.");
                            }
                            return;
                        }

                        IShard remoteShard = new RemoteShard(new DualChannelFactory(), new ShardChannelFormatter(), context, _connectionRestoration);
                        remoteShard.Initialize(sConfig);
                        remoteShard.RegisterShardListener(Common.MiscUtil.CLUSTER_MANAGER, this);
                        lock (_remoteShards)
                        {
                            _remoteShards.Add(shard.Name, remoteShard);
                        }
                    }
                }
            }
        }
        public NodeToCSHeartbeatTask(NodeContext context, MembershipManager manager, IConnectionRestoration connectionRestoration, ClusterConfigurationManager clusterConfigMgr)
        {
            this._context          = context;
            this._clusterConfigMgr = clusterConfigMgr;
            ShardConfiguration sConfig = null;

            if (_clusterConfigMgr != null)
            {
                sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
                if (_clusterConfigMgr.LatestConfiguration != null && _clusterConfigMgr.LatestConfiguration.Deployment != null)
                {
                    _heartbeatInterval = 1000 * _clusterConfigMgr.LatestConfiguration.Deployment.HeartbeatInterval;
                }
            }
            if (sConfig != null && sConfig.Servers != null)
            {
                _node = sConfig.Servers.GetServerNode(_context.LocalAddress.IpAddress.ToString());
            }

            this._membershipManager = manager;

            this._connectionRestoration = connectionRestoration;

            _running     = false;
            _startSignal = new System.Threading.ManualResetEvent(false);
        }
Example #3
0
        public LocalShardCheckHeartbeatTask(IShard shard, NodeContext context, MembershipManager membershipManager, ClusterConfigurationManager clusterConfigMgr)
        {
            this._shard                  = shard;
            this._context                = context;
            this._clusterConfigMgr       = clusterConfigMgr;
            _localShardHeartbeatReporter = new LocalShardHeartbeatReporting(_context.LocalAddress);

            this._membershipManager = membershipManager;
            this._membershipManager.HeartbeatReport = _localShardHeartbeatReporter;
            ShardConfiguration sConfig = null;

            if (_clusterConfigMgr != null)
            {
                sConfig = _clusterConfigMgr.GetShardConfiguration(context.LocalShardName);
            }

            if (sConfig != null && sConfig.NodeHeartbeatInterval > 0)
            {
                this._poolingThreshold = (sConfig.NodeHeartbeatInterval * 2) * 1000;
            }
            _running     = false;
            _startSignal = new ManualResetEvent(false);


            //with the initialization of the heartbeat receiver, we start the send heart beat task.
            _sendHearbeatTask = new LocalShardSendHeartbeatTask(context, shard, _membershipManager, clusterConfigMgr);
        }
Example #4
0
        private void SetShardConfigs(DeploymentConfiguration configuration, out ShardConfiguration localShardConfig, out IDictionary <String, ShardConfiguration> remoteShardConfigs)
        {
            Dictionary <String, ShardConfiguration> remoteConfigDic = new Dictionary <String, ShardConfiguration>();
            ShardConfiguration localShard = null;

            foreach (Common.Configuration.ShardConfiguration shardConfig in configuration.Shards.Values)
            {
                if (shardConfig.Name.Equals(context.LocalShardName, StringComparison.OrdinalIgnoreCase))
                {
                    localShard = shardConfig;
                }
                else
                {
                    //localShard = shardConfig;

                    remoteConfigDic.Add(shardConfig.Name, shardConfig);
                }
            }

            if (localShard == null)
            {
                throw new Alachisoft.NosDB.Common.Exceptions.ConfigurationException("Local Shard Configruation is missing");
            }

            localShardConfig   = localShard;
            remoteShardConfigs = remoteConfigDic;
        }
Example #5
0
        /// <summary>
        /// We need to ask the current primary to quit taking write ops
        /// so that the left over ops can first be replicated
        /// before the actual election mechanism begins.
        /// </summary>
        /// <returns></returns>
        private bool RequestPrimaryToStopOperations()
        {
            ShardConfiguration sConfg = null;
            bool endResult            = false;

            if (_clusterConfigMgr != null)
            {
                sConfg = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
            }

            if (sConfg != null)
            {
                MembershipChangeArgs args = new MembershipChangeArgs();
                args.ChangeType = MembershipChangeArgs.MembershipChangeType.RestrictPrimary;
                args.ServerName = _context.LocalAddress;
                args.ElectionId = _latestMembership.ElectionId;

                DatabaseMessage msg = new DatabaseMessage();
                msg.Payload       = args;
                msg.NeedsResponse = true;
                msg.OpCode        = OpCode.RestrictPrimary;
                msg.MessageType   = MessageType.DBOperation;
                ShardRequestBase <bool> request = _shard.CreateUnicastRequest <bool>(new Server(new Address(_latestMembership.Primary.Name, sConfg.Port), Status.Running), msg);
                IAsyncResult            result  = request.BeginExecute();
                endResult = request.EndExecute(result);
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Info("MembershipMgr.RequestPrimaryToStopOperations()", "Requested primary to stop taking write operations. Primary response: " + endResult.ToString());
                }
            }

            return(endResult);
        }
Example #6
0
        public LocalShardSendHeartbeatTask(NodeContext nodeContext, IShard shard, MembershipManager membershipManager, ClusterConfigurationManager clusterConfigMgr)
        {
            this._nodeContext      = nodeContext;
            this._clusterConfigMgr = clusterConfigMgr;
            ShardConfiguration config = _clusterConfigMgr.GetShardConfiguration(_nodeContext.LocalShardName);//_nodeContext.ConfigurationSession.GetDatabaseClusterConfiguration(_nodeContext.ClusterName).Deployment.GetShardConfiguration(_nodeContext.LocalShardName);

            if (config == null)
            {
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Error("LocalShardSendHeartTask", "shard configuration is null");
                }
                throw new Alachisoft.NosDB.Common.Exceptions.DatabaseException(" shard configuration is null");
            }

            if (config.NodeHeartbeatInterval > 0)
            {
                this._poolingThreshold = (config.NodeHeartbeatInterval) * 1000;
            }
            this._shard             = shard;
            this._membershipManager = membershipManager;

            _running     = false;
            _startSignal = new System.Threading.ManualResetEvent(false);
        }
        public void Configure(IDependencyRegister register)
        {
            var section = ToolSection.Instance;

            if (section == null)
            {
                throw new ConfigurationException("缺少 Projects.Tool 配直节信息。");
            }

            repositoryAssemblies = LoadAssemblies(section, "repository/assembly");
            serviceAssemblies    = LoadAssemblies(section, "service/assembly");

            shardConfig       = new ShardConfiguration(section);
            metadataConfig    = new MetadataConfiguration(repositoryAssemblies);
            interceptorConfig = new InterceptorConfiguation(section);
            repositoryConfig  = new RepositoryConfiguation(repositoryAssemblies, register);
            serviceConfig     = new ServiceConfiguation(serviceAssemblies, register);
            commandConfig     = new CommandConfiguation(serviceAssemblies, register);

            shardConfig.Load();
            metadataConfig.Load();
            interceptorConfig.Load();
            repositoryConfig.Load();
            serviceConfig.Load();
            commandConfig.Load();
        }
Example #8
0
        public override bool TryGetNodeDetail(out NodeDetail nodeDetail)
        {
            NodeDetail         thisNode       = new EndNodeDetail();
            List <string>      childernNaames = new List <string>();
            ShardConfiguration shardConfig    = (ShardConfiguration)Configuration;

            foreach (ServerNode node in shardConfig.Servers.Nodes.Values)
            {
                if (node.Name.Equals(PathChunks[0]))
                {
                    childernNaames.Add(node.Priority.ToString());
                    string[] childPathChunks = new string[this.PathChunks.Length - 1];
                    Array.Copy(this.PathChunks, 1, childPathChunks, 0, this.PathChunks.Length - 1);
                    ServerDetail s1 = new ServerDetail()
                    {
                        IPAddress = node.Name,
                        Priority  = node.Priority
                    };
                    thisNode = new ServerValueDetail(PathChunks[0], PathType.Server, s1, childPathChunks);
                }
            }
            if (PathChunks.Length == 1)
            {
                nodeDetail = thisNode;
                return(true);
            }

            return(thisNode.TryGetNodeDetail(out nodeDetail));
        }
Example #9
0
        // Receives the heartbeats from different nodes which are part of a shard and
        // adds them to the report table.
        public void ReceiveHeartbeat(Address source, HeartbeatInfo heartbeatInfo)
        {
            try
            {
                if (_localShardHeartbeatReporter != null)
                {
                    // We need to verify if the node sending the heartbeat is part of the existing configuration.
                    // Updating the config is a costly process so we check the node in the existing config.
                    // If the node was freshly added in an existing (active) shard, we will not add the heartbeat to the report
                    // until it exists in the local node config instance.
                    if (_clusterConfigMgr != null)
                    {
                        ShardConfiguration sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
                        ServerNode         sNode   = null;
                        if (sConfig != null && sConfig.Servers != null)
                        {
                            sNode = sConfig.Servers.GetServerNode(source.IpAddress.ToString());
                        }
                        if (sNode == null)
                        {
                            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                            {
                                LoggerManager.Instance.ShardLogger.Debug("LocalShardCheckHeartbeatTask.ReceiveHeartbeat() ", "The node " + source + " is not part of the configuration.");
                            }
                            return;
                        }
                    }

                    bool isAnOldNode = _localShardHeartbeatReporter.AddToReport(source, heartbeatInfo);

                    if (!isAnOldNode)
                    {
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Debug("LocalShardCheckHeartbeatTask.ReceiveHeartbeat() ", "Node " + source.IpAddress + " added to the table for the first time. ");
                        }

                        lock (_membershipManager)
                        {
                            _membershipManager.HeartbeatReport = _localShardHeartbeatReporter;
                        }

                        _electionExecTask = new ElectionMechanismExecutionTask(_membershipManager, Activity.NodeJoining, new Server(source, Status.Running));
                        _electionExecTask.Start();
                        OnActivityCompleted();
                    }
                }
            }
            catch (Exception e)
            {
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Error("LocalShardCheckHeartbeatTask.ReceiveHeartbeat() ", e.ToString());
                }
            }
        }
Example #10
0
        public ShardConfiguration GetShardConfiguration(string shardName)
        {
            ShardConfiguration sConfig = null;

            if (LatestConfiguration != null && LatestConfiguration.Deployment != null)
            {
                sConfig = LatestConfiguration.Deployment.GetShard(shardName);
            }
            return(sConfig);
        }
        protected override void ProcessRecord()
        {
            var sConfiguration = new ShardConfiguration
            {
                Port = Port,
                Name = Shard,
                NodeHeartbeatInterval = HeartBeat,
            };

            var serverNodes = new Dictionary <string, ServerNode>();

            var sNode = new ServerNode {
                Name = Server.Split('[', ']')[0]
            };

            int priority = 1;

            if (Server.Contains('['))
            {
                string priorityString = Server.Split('[', ']')[1];
                int.TryParse(priorityString, out priority);
                priority = priority > 3 ? 3 : priority;
            }

            sNode.Priority = priority < 1 ? 1 : priority;
            serverNodes.Add(sNode.Name, sNode);

            sConfiguration.Servers = new ServerNodes();
            if (serverNodes.Count > 0)
            {
                sConfiguration.Servers.Nodes = serverNodes;
            }

            ClusterConfiguration config = new ClusterConfiguration
            {
                Name        = Common.MiscUtil.CLUSTERED,
                DisplayName = Name,
                Deployment  = new DeploymentConfiguration()
            };

            config.Deployment.AddShard(sConfiguration);


            var current = new RemoteConfigurationManager();

            current.CreateCluster(config, new SSPIClientAuthenticationCredential());
            if (current.VerifyConfigurationCluster())
            {
                ConfigurationConnection.ConfigCluster        = current.GetConfigurationClusterConfiguration();
                ConfigurationConnection.ClusterConfiguration = current.GetDatabaseClusterConfig(true);
                ConfigurationConnection.Current = current;
                ConfigurationConnection.UpdateDatabaseClusterInfo();
            }
            SessionState.Path.SetLocation(ProviderUtil.DRIVE_ROOT + ":\\" + ConfigurationConnection.ClusterConfiguration.DisplayName);
        }
        public bool Initialize(ShardConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new DistributorException("Remote Shard Configuration is Null");
            }

            _name      = configuration.Name;
            _shardPort = configuration.Port;
            _servers   = GetShardServerList(configuration);

            return(true);
        }
Example #13
0
        public bool Initialize(ShardConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("remote shard configuration is null");
            }

            this._name      = configuration.Name;
            this._shardPort = configuration.Port;
            this._servers   = GetShardServerList(configuration);

            this._resolveDispute = new ResolveChannelDispute(context, this);

            return(true);
        }
Example #14
0
        public ShardValueDetail(string nodeName, ShardConfiguration configuration, string[] pathChunks)
        {
            NodeName       = nodeName;
            NodeType       = PathType.Shard;
            IsContainer    = true;
            IsValid        = true;
            Configuration  = configuration;
            PathChunks     = pathChunks;
            ChilderanTable = new PrintableTable();
            ChilderanName  = new List <string>();
            ClusterInfo       clusterInfo = ConfigurationConnection.ClusterInfo;
            ShardInfo         shardInfo   = clusterInfo.GetShard(nodeName);
            List <ServerInfo> running     = new List <ServerInfo>();

            if (shardInfo != null)
            {
                if (shardInfo.RunningNodes != null)
                {
                    running = shardInfo.RunningNodes.Values.ToList();
                }
            }
            ChilderanTable.AddHeader("Node IP Address", "Running Status", "Primary Status", "Priority");

            foreach (ServerNode node in configuration.Servers.Nodes.Values)
            {
                ServerInfo serverInfo = null;
                string     isPrimery  = ProviderUtil.NOT_PRIMARY;
                string     isRunning  = ProviderUtil.NOT_RUNNING;
                if (running != null)
                {
                    serverInfo = running.Find(x => x.Address.ip.Equals(node.Name));
                }

                if (serverInfo != null)
                {
                    if (running.Contains(serverInfo))
                    {
                        isRunning = ProviderUtil.RUNNING;
                    }
                    if (shardInfo.Primary != null && serverInfo.Equals(shardInfo.Primary))
                    {
                        isPrimery = ProviderUtil.PRIMARY;
                    }
                }
                ChilderanTable.AddRow(node.Name, isRunning, isPrimery, node.Priority.ToString());
                ChilderanName.Add(node.Name);
            }
        }
Example #15
0
        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.");
            }
        }
Example #16
0
        public void AddShardItem_Test()
        {
            ShardConfiguration shardConfiguration = new ShardConfiguration(3);
            IShardKeyAlgorithm shardKeyAlgorithm  = new EvenlyDistributedShardKeyAlgorithm(shardConfiguration);
            InMemoryDB         db = new InMemoryDB(shardConfiguration, shardKeyAlgorithm);

            AddCustomer(db, 1);
            AddCustomer(db, 2);
            AddCustomer(db, 3);
            AddCustomer(db, 4);

            // 3 shards
            var stats = db.GetTotalShardItems();

            Assert.AreEqual(2, stats[0].ItemsCount);
            Assert.AreEqual(1, stats[1].ItemsCount);
            Assert.AreEqual(1, stats[2].ItemsCount);

            // 4 shards
            db.AddShard();
            AddCustomer(db, 5);
            AddCustomer(db, 6);

            stats = db.GetTotalShardItems();
            Assert.AreEqual(3, stats[0].ItemsCount);
            Assert.AreEqual(2, stats[1].ItemsCount);
            Assert.AreEqual(1, stats[2].ItemsCount);

            // 5 shards
            db.AddShard();

            AddCustomer(db, 7);
            AddCustomer(db, 8);
            AddCustomer(db, 9);
            AddCustomer(db, 10);
            AddCustomer(db, 11);

            stats = db.GetTotalShardItems();
            Assert.AreEqual(4, stats[0].ItemsCount);
            Assert.AreEqual(3, stats[1].ItemsCount);
            Assert.AreEqual(2, stats[2].ItemsCount);
            Assert.AreEqual(1, stats[3].ItemsCount);
            Assert.AreEqual(1, stats[4].ItemsCount);
        }
        private IList <ConfigChangeParams> CheckForLocalShardConfigChange(ShardConfiguration oldConfig, ShardConfiguration latestConfig)
        {
            IList <ConfigChangeParams> configChanges = new List <ConfigChangeParams>();

            if (oldConfig != null && latestConfig != null)
            {
                if (oldConfig.Servers != null && latestConfig.Servers != null)
                {
                    IDictionary <string, ServerNode> oldNodes = oldConfig.Servers.Nodes;
                    if (oldNodes != null)
                    {
                        foreach (KeyValuePair <string, ServerNode> oldNode in oldNodes)
                        {
                            ServerNode latestNode = latestConfig.Servers.GetServerNode(oldNode.Value.Name);
                            if (latestNode != null)
                            {
                                if (oldNode.Value.Priority != latestNode.Priority)
                                {
                                    configChanges.Add(new ConfigChangeParams(new Address(latestNode.Name, latestConfig.Port), ChangeType.PriorityChanged));
                                }
                            }
                            else
                            {
                                configChanges.Add(new ConfigChangeParams(new Address(oldNode.Value.Name, oldConfig.Port), ChangeType.NodeRemoved));
                            }
                        }
                    }
                    IDictionary <string, ServerNode> latestNodes = latestConfig.Servers.Nodes;
                    if (latestNodes != null)
                    {
                        foreach (KeyValuePair <string, ServerNode> newNode in latestNodes)
                        {
                            ServerNode oldNode = oldConfig.Servers.GetServerNode(newNode.Value.Name);
                            if (oldNode == null)
                            {
                                configChanges.Add(new ConfigChangeParams(new Address(newNode.Value.Name, latestConfig.Port), ChangeType.NodeAdded));
                            }
                        }
                    }
                }
            }
            return(configChanges);
        }
Example #18
0
        protected override void ProcessRecord()
        {
            var sConfiguration = new ShardConfiguration
            {
                Port = Port,
                Name = Name,
                NodeHeartbeatInterval = HeartBeat
            };

            var serverNodes = new Dictionary <string, ServerNode>();
            var sNode       = new ServerNode {
                Name = Server.Split('[', ']')[0]
            };
            int priority = 1;

            if (Server.Contains('['))
            {
                string priorityString = Server.Split('[', ']')[1];
                int.TryParse(priorityString, out priority);
                priority = priority > 3 ? 3 : priority;
            }

            sNode.Priority = priority < 1 ? 1 : priority;
            serverNodes.Add(sNode.Name, sNode);
            sConfiguration.Servers = new ServerNodes();

            if (serverNodes.Count > 0)
            {
                sConfiguration.Servers.Nodes = serverNodes;
            }
            try
            {
                if (ConfigurationConnection.Current.AddShardToCluster(sConfiguration, null))
                {
                    WriteObject("Shard Added Sucessfully");
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Example #19
0
        /// <summary>
        /// function needs to be shifted from here.
        /// this function provides a mini election feasibility check to avoid continuous triggering of the
        /// election mechanism.
        /// Steps:
        /// 1. Does the node possess a majority of the connections.
        /// 2. If yes, proceed to the next step where the primary is hunted for in the existing heartbeat report table.
        /// </summary>
        /// <param name="report"></param>
        /// <returns></returns>
        private bool AreElectionsFeasible(LocalShardHeartbeatReporting report, ShardConfiguration sConfig)
        {
            IList <Address> activeServers = report.GetReportTable.Keys.ToList();

            if (activeServers.Count < (int)Math.Ceiling((double)sConfig.Servers.Nodes.Count / 2))
            {
                return(false);
            }
            else
            {
                if (report.PrimaryExists())
                {
                    // We verify if a primary exists on any of the nodes at any given point in time and if a channel exists
                    // because there is a possibility that the primary is not stepping down and is not a valid primary either
                    // (catering for split - brain scenarios)
                    return(!ChannelExists(report.GetCurrentPrimary()));
                }
            }
            return(true);
        }
Example #20
0
        public void ChangeShardCount_Test()
        {
            ShardConfiguration shardConfiguration = new ShardConfiguration(3);
            IShardKeyAlgorithm shardKeyAlgorithm  = new EvenlyDistributedShardKeyAlgorithm(shardConfiguration);
            InMemoryDB         dataProvider       = new InMemoryDB(shardConfiguration, shardKeyAlgorithm);
            int shardId;

            shardId = dataProvider.GetShardId("1");
            Assert.AreEqual(1, shardId);
            shardId = dataProvider.GetShardId("2");
            Assert.AreEqual(2, shardId);
            shardId = dataProvider.GetShardId("3");
            Assert.AreEqual(3, shardId);
            shardId = dataProvider.GetShardId("4");
            Assert.AreEqual(1, shardId);
            shardId = dataProvider.GetShardId("123");
            Assert.AreEqual(3, shardId);

            // 3 + 1 shards
            dataProvider.AddShard();

            shardId = dataProvider.GetShardId("1");
            Assert.AreEqual(1, shardId);
            shardId = dataProvider.GetShardId("2");
            Assert.AreEqual(2, shardId);
            shardId = dataProvider.GetShardId("3");
            Assert.AreEqual(3, shardId);
            shardId = dataProvider.GetShardId("4");
            Assert.AreEqual(1, shardId);
            shardId = dataProvider.GetShardId("123");
            Assert.AreEqual(3, shardId);
            shardId = dataProvider.GetShardId("5");
            Assert.AreEqual(1, shardId);
            shardId = dataProvider.GetShardId("6");
            Assert.AreEqual(2, shardId);
            shardId = dataProvider.GetShardId("7");
            Assert.AreEqual(3, shardId);
            shardId = dataProvider.GetShardId("8");
            Assert.AreEqual(4, shardId);
        }
Example #21
0
        private IList <Server> GetShardServerList(ShardConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("remote shard configuration is null");
            }

            IList <Server> serverList = new List <Server>();

            int shardPort = configuration.Port;

            if (configuration.Servers != null && configuration.Servers.Nodes != null)
            {
                foreach (Alachisoft.NosDB.Common.Configuration.ServerNode node in configuration.Servers.Nodes.Values)
                {
                    Server server = new Server(new Address(node.Name, shardPort), Status.Stopped);
                    serverList.Add(server);
                }
            }

            return(serverList);
        }
Example #22
0
        public ShardedDb(ShardConfiguration shardConfiguration, IShardKeyAlgorithm algorithm,
                         IMainShardDataProvider mainShardDataProvider, IConnectionProvider connectionProvider)
        {
            this._shardConfiguration    = shardConfiguration;
            this._shardKeyAlgorithm     = algorithm;
            this._mainShardDataProvider = mainShardDataProvider;
            this._connectionProvider    = connectionProvider;
            subShardMap = new Dictionary <int, V>();
            _shardMap   = new Dictionary <string, int>();
            _shards     = new List <int>();

            var connection = connectionProvider.GetMainConnectionString();

            mainShardDataProvider.Initialize(connection);

            mainShardDataProvider.LoadShardMap(_shards, _shardMap);

            if (subShardMap.Count < shardConfiguration.ShardCount)
            {
                SetupShard(shardConfiguration.ShardCount - subShardMap.Count);
            }
        }
Example #23
0
        public bool Initialize(ShardConfiguration configuration)
        {
            if (configuration == null)
            {
                return(false);
            }

            this.Name = configuration.Name;
            IPAddress localIP = GetLocalAddress();

            if (context != null)
            {
                context.LocalAddress = new Common.Net.Address(localIP, configuration.Port);
            }
            _membershipManager = new MembershipManager(this, context, _clusterConfigMgr);


            lock (_mutexOnnodeRole)
            {
                if (NodeRole != NodeRole.Intermediate)
                {
                    NodeRole = NodeRole.None;
                }
            }

            this._shardPeersList = GetPeersList(configuration.Servers.Nodes.Values.ToArray(), configuration.Port);
            //an old copy of the membership is required at the time when the node joins for comparison purposes.
            //_oldMembership = context.ConfigurationSession.GetMembershipInfo(context.ClusterName, context.LocalShardName);
            //this._shardPeersList = GetRunningPeersList(configuration.Port);
            //this._shardPeersList = GetRunningPeersList(_oldMembership.Servers, configuration.Port);
            this._traceProvider = new TraceProvider();


            _resolveDispute = new ResolveChannelDispute(context, this);


            return(true);
        }
        private IList <Server> GetShardServerList(ShardConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new DistributorException(ErrorCodes.Distributor.SHARD_CONFIGURATION_NULL, new string[] { this.Name });
            }

            IList <Server> serverList = new List <Server>();

            int shardPort = configuration.Port;

            if (configuration.Servers == null || configuration.Servers.Nodes == null)
            {
                return(serverList);
            }
            foreach (ServerNode node in configuration.Servers.Nodes.Values)
            {
                Server server = new Server(new Address(node.Name, shardPort), Status.Stopped);
                serverList.Add(server);
            }

            return(serverList);
        }
Example #25
0
 public SqlMainShardDataProvider(ShardConfiguration shardConfiguration, IShardKeyAlgorithm algorithm)
 {
     _shardConfiguration = shardConfiguration;
     _shardKeyAlgorithm  = algorithm;
 }
Example #26
0
 public SqlDb(ShardConfiguration shardConfiguration, IShardKeyAlgorithm algorithm) :
     base(shardConfiguration, algorithm,
          new SqlMainShardDataProvider(shardConfiguration, algorithm),
          new SqlConnectionProvider())
 {
 }
Example #27
0
        // the method which runs in a thread.
        public void Run()
        {
            LoggerManager.Instance.SetThreadContext(new LoggerContext()
            {
                ShardName = _context.LocalShardName != null ? _context.LocalShardName : "", DatabaseName = ""
            });
            _context.StatusLatch.WaitForAny(NodeStatus.Running);
            _startSignal.WaitOne();
            while (_running)
            {
                IDictionary <Address, HeartbeatInfo> reportTable = null;
                try
                {
                    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("LocalShardCheckHeartbeatTask.Run() ", "The shard (or the nodes of the shard) " +
                                                                    _context.LocalShardName +
                                                                    " does not exist in the configuration.");
                        }
                        return;
                    }
                    reportTable = _localShardHeartbeatReporter.GetReportTable;
                    if (reportTable != null && reportTable.Count > 0)
                    {
                        CheckHeartbeats(reportTable);

                        IList <Address> tentativeLostNodes = CheckForLostNodes(reportTable);
                        if (tentativeLostNodes != null && tentativeLostNodes.Count > 0)
                        {
                            // 1. These are the nodes lost.
                            // 2. The lost node needs to be removed from the heartbeats table and the missing heartbeats
                            // 3. Elections will be triggered when a node is lost.

                            foreach (var node in tentativeLostNodes)
                            {
                                if (_localShardHeartbeatReporter.GetReportTable.ContainsKey(node) &&
                                    !ChannelExists(sConfig.Servers.GetServerNode(node.IpAddress.ToString())))
                                {
                                    if (LoggerManager.Instance.ShardLogger != null &&
                                        LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                                    {
                                        LoggerManager.Instance.ShardLogger.Debug("LocalShard.CheckHeartbeatTask",
                                                                                 "did not receive heart beat from " + node);
                                    }


                                    //_localShardHeartbeatReporter.RemoveFromReport(node);
                                    OnActivityTriggered(Activity.NodeLeaving, node);

                                    lock (_membershipManager)
                                    {
                                        _membershipManager.HeartbeatReport =
                                            (LocalShardHeartbeatReporting)_localShardHeartbeatReporter;
                                    }
                                    _electionExecTask = new ElectionMechanismExecutionTask(_membershipManager,
                                                                                           Activity.NodeLeaving, new Server(node, Status.Stopped));
                                    _electionExecTask.Start();
                                    OnActivityCompleted();
                                }
                                else
                                {
                                    if (LoggerManager.Instance.ShardLogger != null &&
                                        LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                                    {
                                        LoggerManager.Instance.ShardLogger.Debug("LocalShard.CheckHeartbeatTask",
                                                                                 "did not receive heart beat from " + node + ", however channel is connected");
                                    }
                                }
                            }
                        }
                        //if no primary is set, we proceed to the following steps:
                        if (!_shard.NodeRole.Equals(NodeRole.Intermediate) && _membershipManager.LatestMembership == null ||
                            (      /*_membershipManager.LatestMembership != null &&*/
                                (_membershipManager.LatestMembership.Primary == null ||
                                 ( /*_membershipManager.LatestMembership.Primary != null &&*/
                                     !ChannelExists(_membershipManager.LatestMembership.Primary)))))
                        {
                            //First, check if the conduction of elections is feasible.
                            //If yes, the actual election mechanism is triggered.
                            if (AreElectionsFeasible(_localShardHeartbeatReporter, sConfig))
                            {
                                lock (_membershipManager)
                                {
                                    _membershipManager.HeartbeatReport =
                                        (LocalShardHeartbeatReporting)_localShardHeartbeatReporter;
                                }

                                _electionExecTask = new ElectionMechanismExecutionTask(_membershipManager, Activity.GeneralElectionsTriggered, null);
                                _electionExecTask.Start();
                            }
                            //RTD: badddd logic.
                            //else if (_localShardHeartbeatReporter.PrimaryExists() &&
                            //         _localShardHeartbeatReporter.GetCurrentPrimary() != null &&
                            //         ChannelExists(_localShardHeartbeatReporter.GetCurrentPrimary()))
                            //{
                            //    ServerNode currentPrimaNode = _localShardHeartbeatReporter.GetCurrentPrimary();
                            //    if (currentPrimaNode != null)
                            //    {
                            //        if (LoggerManager.Instance.ShardLogger != null &&
                            //            LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                            //            LoggerManager.Instance.ShardLogger.Debug("LocalShard.CheckHeartbeatTask",
                            //                "no primary set so far, setting " + currentPrimaNode.Name +
                            //                " as primary as other nodes are reporting");

                            //        MembershipChangeArgs args = new MembershipChangeArgs();
                            //        args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimarySet;
                            //        args.ElectionId = _localShardHeartbeatReporter.GetCurrentElectionId();
                            //        args.ServerName = new Address(currentPrimaNode.Name, sConfig.Port);
                            //        ((LocalShard)_shard).OnMembershipChanged(args);
                            //    }
                            //}
                        }
                        LogMembership();
                    }
                }
                catch (ThreadAbortException e)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled && _checkHbThread != null)
                    {
                        LoggerManager.Instance.ShardLogger.Error(_checkHbThread.Name, "Task aborted.");
                    }
                    break;
                }
                catch (Exception e)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("LocalShardCheckHeartbeatTask.Run() ", e.ToString());
                    }
                }

                lock (_syncMutex)
                {
                    Monitor.Wait(_syncMutex, _poolingThreshold);
                }
                _startSignal.WaitOne();
            }
        }
Example #28
0
        internal ElectionVote CastVote(Election election, Membership existingMembership, HeartbeatInfo info)
        {
            if (election == null || election.ElectionId == null)
            {
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Warn("ElectionManager.CastVote()", "Invalid election.");
                }
                return(null);
            }
            ElectionVote vote = new ElectionVote();

            vote.RequestingNode      = election.ElectionId.RequestingNode;
            vote.Sourcenode          = new ServerNode();
            vote.Sourcenode.Name     = _context.LocalAddress.IpAddress.ToString();
            vote.Sourcenode.Priority = (int)LocalServerPriority;
            if (existingMembership != null && (election.ElectionType == ElectionType.GeneralElections && existingMembership.Primary == null) || election.ElectionType == ElectionType.TakeoverElections)
            {
                if (election.RequestingServerInfo.LastOperationId > LocalServerInfo().LastOperationId)
                {
                    vote.NodeVote = ElectionVote.Vote.yes;
                }
                else if (election.RequestingServerInfo.LastOperationId == LocalServerInfo().LastOperationId)
                {
                    if (election.ElectionId.RequestingNode.Priority <= (int)LocalServerPriority)
                    {
                        vote.NodeVote = ElectionVote.Vote.yes;
                    }
                    else
                    {
                        ShardConfiguration sConfig = null;
                        if (_clusterConfigMgr != null)
                        {
                            sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
                        }
                        int configuredNodes = 0;
                        if (sConfig != null || sConfig.Servers != null)
                        {
                            configuredNodes = sConfig.Servers.Nodes.Count;
                        }
                        if (info != null && info.CSStatus == ConnectivityStatus.Connected && (configuredNodes != null && existingMembership.Servers.Count >= configuredNodes / 2))
                        {
                            vote.NodeVote = ElectionVote.Vote.no;
                        }
                        else
                        {
                            vote.NodeVote = ElectionVote.Vote.yes;
                        }
                    }
                }
                else
                {
                    vote.NodeVote = ElectionVote.Vote.no;
                }
            }
            else
            {
                vote.NodeVote = ElectionVote.Vote.no;
            }

            return(vote);
        }
        public void Run()
        {
            LoggerManager.Instance.SetThreadContext(new LoggerContext()
            {
                ShardName = _context.LocalShardName != null ? _context.LocalShardName : "", DatabaseName = ""
            });
            _context.StatusLatch.WaitForAny(NodeStatus.Running);
            _startSignal.WaitOne();

            if (_context.ConfigurationSession != null)
            {
                ((OutProcConfigurationSession)_context.ConfigurationSession).RegisterListener(this);
            }

            while (_running)
            {
                try
                {
                    if (_node == null)
                    {
                        _clusterConfigMgr.UpdateClusterConfiguration();
                    }

                    if (_clusterConfigMgr != null)
                    {
                        ShardConfiguration sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
                        if (sConfig != null && sConfig.Servers != null)
                        {
                            _node = sConfig.Servers.GetServerNode(_context.LocalAddress.IpAddress.ToString());
                        }
                    }
                    if (_node == null && LoggerManager.Instance.ShardLogger != null &&
                        LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Warn("NodeToCSHeartbeatTask.Run() ", "Node " + _context.LocalAddress.ToString() +
                                                                " is not part of the configuration.");
                        return;
                    }
                    OperationId lastOpId = null;
                    if (_membershipManager != null && _membershipManager.LatestMembership != null && _membershipManager.LatestMembership.Primary != null && _membershipManager.LatestMembership.Primary.Name.Equals(_context.LocalAddress.IpAddress.ToString()))
                    {
                        lastOpId = _membershipManager.GetLastOperationId;
                    }
                    Stopwatch watch = new Stopwatch();
                    watch.Start();
                    _heartbeatInterval =
                        _context.ConfigurationSession.ReportHeartbeat(_context.ClusterName, _context.LocalShardName,
                                                                      _node, _membershipManager.LatestMembership, lastOpId) * 1000;
                    watch.Stop();
                    _csStatus = ConnectivityStatus.Connected;
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("NodeToCSHeartbeatTask.Run() ", "Heartbeat sent to the CS at " +
                                                                 DateTime.Now.ToString() + " time taken to report heartbeat :" + watch.Elapsed.TotalSeconds);
                    }
                    if (_heartbeatInterval > 0 && (watch.Elapsed.TotalSeconds > _heartbeatInterval / 2))
                    {
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Error("NodeToCSHeartbeatTask.Run() ", "Heartbeat sent to the CS at " +
                                                                     DateTime.Now.ToString() + " time taken to report heartbeat :" + watch.Elapsed.TotalSeconds + " which is greater than half of the hb interval.");
                        }
                    }
                }
                catch (ThreadAbortException e)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled && _nodeToCSThread != null)
                    {
                        LoggerManager.Instance.ShardLogger.Error(_nodeToCSThread.Name, "Task aborted.");
                    }
                    break;
                }
                //the following should only be done when a connection exception occurs.
                catch (ChannelException e)
                {
                    if (LoggerManager.Instance.ShardLogger != null)
                    {
                        if (LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Error("NodeToCSHeartbeatTask.Run()  ", e.ToString());
                        }
                        if (LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Debug("NodeToCSHeartbeatTask.Run() ",
                                                                     "On CS disconnected process of the membership manager begins execution at " +
                                                                     DateTime.Now.ToString());
                        }
                    }

                    _csStatus = ConnectivityStatus.NotConnected;
                    _membershipManager.OnCSDisconnected();
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("NodeToCSHeartbeatTask.Run() ", "The NodeToCS task paused at " +
                                                                 DateTime.Now.ToString());
                    }

                    //foreach (var cluster in ManagementServer.s_DbmNodeConfiguration.DbmClusters.ClustersConfigurations)
                    //{
                    //    string csIp = cluster.ConfigServers.Nodes[0].Name;
                    //    int csPort = cluster.ConfigServers.Nodes[0].Port;

                    //    BrokenConnectionInfo info = new BrokenConnectionInfo();
                    //    info.BrokenAddress = new Address(csIp, csPort);
                    //    info.SessionType = Common.Communication.SessionTypes.Management;

                    //    _connectionRestoration.RegisterListener(info, this,_context.LocalShardName);
                    //}


                    this.Pause();
                }
                catch (Exception e)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsErrorEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Error("NodeToCSHbTask.Run() General Exception: ",
                                                                 e.ToString());
                    }

                    if (e.Message.Contains("No configuration server is available to process the request"))
                    {
                        _csStatus = ConnectivityStatus.NotConnected;
                        _membershipManager.OnCSDisconnected();
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Debug("NodeToCSHeartbeatTask.Run() ", "The NodeToCS task paused at " +
                                                                     DateTime.Now.ToString());
                        }
                        this.Pause();
                    }
                }
                Stopwatch sleepWatch = new Stopwatch();
                sleepWatch.Start();
                Thread.Sleep(_heartbeatInterval);
                _startSignal.WaitOne();
                sleepWatch.Stop();

                if (sleepWatch.Elapsed.TotalMilliseconds > (_heartbeatInterval + 2000))
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("NodeToCSHeartbeatTask.Run() ", "CS task waited for  " + sleepWatch.Elapsed.TotalSeconds);
                    }
                }
            }
        }
        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;
            }
        }