/// <summary>
 /// Processes a join request from another node
 /// </summary>
 /// <param name="joinUpdate">The details of the node requesting to join the cluster</param>
 private void ProcessJoin(GossipNode joinUpdate) {
     try {
         //Verify node has valid ID
         if (joinUpdate.NodeId == null) {
             //TODO: Log Error
             return;
         }
         //Verify it's not already in the registry
         GossipNode existingNode = registry.GossipList.FirstOrDefault(n => n.NodeId.Equals(joinUpdate.NodeId));
         if (existingNode != null) {
             if (existingNode.Status != GossipStatus.Unknown &&
                 existingNode.Status != GossipStatus.Suspended) {
                 //TODO: Log Error
                 return;
             }
         }
         if (string.IsNullOrEmpty(joinUpdate.Partition)) {
             //TODO: Log Error
             return;
         }
         joinUpdate.Status = GossipStatus.Active;
         joinUpdate.GossipHeartbeats = 0;
         joinUpdate.SuspectMatrix = new Dictionary<Guid, bool>();
         joinUpdate.UpdateVersion = DateTime.Now.Ticks;
         joinUpdate.Suspect = false;
         lock (registryLock) {
             registry.GossipList.Add(joinUpdate);
         }
         if (this.OnNodeAdded != null) {
             this.OnNodeAdded(this, joinUpdate);
         }
     } catch (Exception ex) {
         //TODO: Log Error
     }
 }
 /// <summary>
 /// Processes a leave request from another node
 /// </summary>
 /// <param name="leaveUpdate">The details of the node requesting to leave the cluster</param>
 private void ProcessLeave(GossipNode leaveUpdate) {
     // Update status of node to "Suspended"
     lock (registryLock) {
         var node = registry.GossipList.FirstOrDefault(n => n.NodeId.Equals(leaveUpdate.NodeId));
         if (node == null) {
             //TODO: Log Error
             return;
         }
         node.Status = GossipStatus.Suspended;
     }
     if (this.OnNodeSuspended != null) {
         this.OnNodeSuspended(this, leaveUpdate);
     }
 }
        private void Init() {
            List<string> endpointList = new List<string>();
            foreach (IPEndPoint e in listenerAddressList) {
                endpointList.Add(string.Format("tcp://{0}:{1}", e.Address.ToString(), e.Port.ToString()));
            }

            localNode = new GossipNode() {
                ClusterKey = clusterKey,
                GossipHeartbeats = 0,
                ListenerAddressList = endpointList.ToArray(),
                NodeId = Guid.NewGuid(),
                HostName = Dns.GetHostName(),
                Partition = partitionName,
                Status = GossipStatus.Active,
                Suspect = false,
                SuspectMatrix = new Dictionary<Guid, bool>(),
                UpdateVersion = DateTime.Now.Ticks
            };
            //Set node roles
            List<string> nodeRoles = new List<string>();
            if (!string.IsNullOrEmpty(roles)) {
                string[] arrRoles = roles.Split(',');
                foreach (string r in arrRoles) {
                    if (!string.IsNullOrEmpty(r)) {
                        nodeRoles.Add(r.Trim());
                    }
                }
            }
            localNode.ClusterRoles = nodeRoles.ToArray();
        }