Ejemplo n.º 1
0
        private ManagerElectionState Elect(CancellationToken cancellationToken)
        {
            var electResult = _election.Elect(cancellationToken);
            var electState  = electResult.State;

            LogWriter.Write(string.Format("elect result: {0}, current manager: {1}", electResult.IsSuccess, electState.CurrentManagerId));
            ManagerElectCompletedEventHandler?.Invoke(electResult);
            return(electState);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 监控Manager选举
        /// </summary>
        public void Watch(CancellationToken cancellationToken = default(CancellationToken))
        {
            var key = GetManagerKey();

            LogWriter.Write("start first manager election");

            // 上来就先选举一次,看看结果,以启动Manager或Worker剧本
            var   electResult = Elect(out ulong modifyIndex, cancellationToken);
            ulong waitIndex   = modifyIndex++;

            ManagerElectCompletedEventHandler?.Invoke(electResult, _managerId);

            var waitTime             = _defaultWatchInterval;
            var offlineConfirmAmount = _defaultOfflineConfirmAmount;

            do
            {
                cancellationToken.ThrowIfCancellationRequested();

                try
                {
                    LogWriter.Write("start manager watch query", LogLevel.Debug);

                    // 阻塞查询
                    var kv = ConsulKV.BlockGet(key, waitTime, waitIndex, cancellationToken);

                    // 可能Key被删除了
                    if (kv == null)
                    {
                        LogWriter.Write("manager is not exists, start election right away");
                        electResult = Elect(out modifyIndex, cancellationToken);
                        waitIndex   = modifyIndex++;
                        LogWriter.Write(string.Format("elect result: {0}, current manager: {1}", electResult, _managerId));
                        ManagerElectCompletedEventHandler?.Invoke(electResult, _managerId);
                    }
                    else
                    {
                        waitIndex = kv.ModifyIndex++;

                        // 如果Session为空,则说明Manager下线了
                        // 但是这时候可能Manager出现了闪断,为了减少Manager重新选举导致的处理工作,节点应该再确认两次,
                        // 如果在确认过程中Manager又上线了,则应该优先再次当选为Manager,减少不必要的麻烦
                        if (string.IsNullOrWhiteSpace(kv.Session))
                        {
                            LogWriter.Write(string.Format("manager session is empty, last manager is {0}", Encoding.UTF8.GetString(kv.Value)));

                            // 如果上一个Manager是当前成员,则马上重试
                            if (Encoding.UTF8.GetString(kv.Value) == _memberId)
                            {
                                LogWriter.Write("last manager is me, start election right away");
                                electResult = Elect(out modifyIndex, cancellationToken);
                                waitIndex   = modifyIndex++;
                                LogWriter.Write(string.Format("elect result: {0}, current manager: {1}", electResult, _managerId));
                                ManagerElectCompletedEventHandler?.Invoke(electResult, _managerId);
                            }
                            else
                            {
                                if (offlineConfirmAmount == 0)
                                {
                                    LogWriter.Write("last manager not wake for a long time, start election right away", LogLevel.Info);
                                    electResult = Elect(out modifyIndex, cancellationToken);
                                    waitIndex   = modifyIndex++;
                                    LogWriter.Write(string.Format("elect result: {0}, current manager: {1}", electResult, _managerId));
                                    ManagerElectCompletedEventHandler?.Invoke(electResult, _managerId);
                                }
                                else
                                {
                                    LogWriter.Write("wait last manager ...", LogLevel.Info);
                                    waitTime = _confirmWatchInterval;
                                    offlineConfirmAmount--;
                                    continue;
                                }
                            }
                        }
                    }

                    offlineConfirmAmount = _defaultOfflineConfirmAmount;
                    waitTime             = _defaultWatchInterval;
                }
                catch (Exception ex)
                {
                    LogWriter.Write("Manager选举监控异常", ex);
                    Thread.Sleep(3000);
                }
            }while (true);
        }