コード例 #1
0
ファイル: GossipStrategy.cs プロジェクト: vordoom/jac-mp
        /// <summary>
        /// 
        /// </summary>
        /// <param name="result"></param>
        private Dictionary<Uri, UpdateResult> UpdateMembers(NodeInformation[] nodesInformation)
        {
            var results = new Dictionary<Uri, UpdateResult>();

            foreach (var n in nodesInformation)
            {
                if (n != null && n.Address != null)
                    results[n.Address] = UpdateMember(n);
            }

            return results;
        }
コード例 #2
0
ファイル: Emulator.cs プロジェクト: vordoom/jac-mp
        public NodeInformation[] Ping(Uri targetUri, NodeInformation[] membersInformation)
        {
            if (Fail)
                throw new Exception(string.Format("Node {0} is failed", LocalUri));

            if (_env.RandomFailure())
                throw new Exception("Network exception (local)");

            var transport = _env.Transports[targetUri] as GossipEmulatorTransport;

            return transport.IncomingPingCallback(transport.LocalUri, membersInformation);
        }
コード例 #3
0
ファイル: GossipStrategy.cs プロジェクト: vordoom/jac-mp
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newNodeInfo"></param>
        private UpdateResult UpdateMember(NodeInformation newNodeInfo)
        {
            if (newNodeInfo.Address == _localUri)
                return UpdateResult.IsOrigianl;

            MemberInfo localNodeInfo;
            if (_membersList.TryGetValue(newNodeInfo.Address, out localNodeInfo) == false)
            {
                AddNewNode(newNodeInfo.Address, newNodeInfo.Hearbeat);

                return UpdateResult.IsNew;
            }

            if (localNodeInfo.Heartbeat < newNodeInfo.Hearbeat)
            {
                localNodeInfo.Heartbeat = newNodeInfo.Hearbeat;
                localNodeInfo.Timestamp = _timeStamp;

                if (localNodeInfo.State != MemberState.Ok)
                {
                    localNodeInfo.State = MemberState.Ok;

                    return UpdateResult.IsNew;
                }

                return UpdateResult.IsUpdated;
            }

            return UpdateResult.IsOrigianl;
        }
コード例 #4
0
ファイル: GossipStrategy.cs プロジェクト: vordoom/jac-mp
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nodeUri"></param>
        private NodeInformation[] SendPing(Uri nodeUri, NodeInformation[] membersInformation)
        {
            _log.DebugFormat("{0} \t sending ping request to {1}", _localUri, nodeUri);

            try
            {
                return _transport.Ping(nodeUri, membersInformation);
            }
            catch (Exception ex)
            {
                _log.Debug(string.Format("Failed to ping node {0}", nodeUri), ex);

                return null;
            }
        }
コード例 #5
0
ファイル: GossipStrategy.cs プロジェクト: vordoom/jac-mp
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nodesInformation"></param>
        /// <param name="processFailedNodes"></param>
        private void ProcessUpdates(NodeInformation[] nodesInformation, bool processFailedNodes = false)
        {
            lock (_syncRoot)
            {
                var membersState = UpdateMembers(nodesInformation);

                Node[] newMembers = membersState.Where(a => a.Value == UpdateResult.IsNew).Select(a => _membersList[a.Key].NodeData).ToArray();
                Node[] failedMembers = null;

                if (processFailedNodes)
                {
                    // process not responding nodes -> mark as failed
                    var toMarkAsFail = _membersList.Where(a => a.Value.Timestamp < _timeStamp - _configuration.FailTimeout).Select(a => a.Value);
                    foreach (var v in toMarkAsFail)
                        v.State = MemberState.Failed;

                    failedMembers = toMarkAsFail.Select(a => a.NodeData).ToArray();

                    // process nodes to remove
                    var toRemove = _membersList.Where(a => a.Value.Timestamp < _timeStamp - _configuration.RemoveTimeout).Select(a => a.Value.NodeData.Address).ToArray();
                    foreach (var uri in toRemove)
                    {
                        MemberInfo info;
                        _membersList.TryRemove(uri, out info);
                    }
                }

                Task.Run(() => RaiseNotifications(newMembers, failedMembers));
            }
        }
コード例 #6
0
ファイル: GossipStrategy.cs プロジェクト: vordoom/jac-mp
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nodesInformation"></param>
        /// <returns></returns>
        private NodeInformation[] OnPingReceived(Uri senderUri, NodeInformation[] membersInformation)
        {
            if (membersInformation == null)
                throw new ArgumentNullException("membersInformation");

            _log.DebugFormat("{0} \t received ping request from {1}", _localUri, senderUri);

            Interlocked.Increment(ref _heartbeat);

            ProcessUpdates(membersInformation);

            if (_configuration.InformationExchangePattern == InformationExchangePattern.Pull ||
                _configuration.InformationExchangePattern == InformationExchangePattern.PushPull)
                return GetMembersInformation(includingLocal: true);
            else
                return new NodeInformation[] { GetLocalNodeInformation() };
        }
コード例 #7
0
ファイル: GossipStrategy.cs プロジェクト: vordoom/jac-mp
        /// <summary>
        /// Ping nodes and collect updates.
        /// </summary>
        /// <returns>Collected updates from all nodes.</returns>
        private NodeInformation[] GetUpdates()
        {
            var pingNodes = GetRandomNodes();
            var updatesQueue = new Queue<NodeInformation>();
            NodeInformation[] membersInformation = null;

            if (_configuration.InformationExchangePattern == InformationExchangePattern.Push ||
                _configuration.InformationExchangePattern == InformationExchangePattern.PushPull)
                membersInformation = GetMembersInformation(includingLocal: true);
            else
                membersInformation = new NodeInformation[] { GetLocalNodeInformation() };

            // ping nodes
            foreach (var uri in pingNodes)
            {
                var result = SendPing(uri, membersInformation);

                if (result != null)
                    updatesQueue.EnqueueAll(result);
            }

            // process results
            Dictionary<Uri, long> updates = new Dictionary<Uri, long>();

            while (updatesQueue.Count > 0)
            {
                NodeInformation r = updatesQueue.Dequeue();

                if (updates.ContainsKey(r.Address) == false)
                    updates[r.Address] = r.Hearbeat;
                else if (updates[r.Address] < r.Hearbeat)
                    updates[r.Address] = r.Hearbeat;
            }

            return updates.Select(a => new NodeInformation() { Address = a.Key, Hearbeat = a.Value }).ToArray();
        }