private void HandleInternalReplication(DatabaseRecord newRecord, List <OutgoingReplicationHandler> instancesToDispose) { var newInternalDestinations = newRecord.Topology?.GetDestinations(_server.NodeTag, Database.Name, newRecord.DeletionInProgress, _clusterTopology, _server.Engine.CurrentState); var internalConnections = DatabaseTopology.FindChanges(_internalDestinations, newInternalDestinations); if (internalConnections.RemovedDestiantions.Count > 0) { var removed = internalConnections.RemovedDestiantions.Select(r => new InternalReplication { NodeTag = _clusterTopology.TryGetNodeTagByUrl(r).NodeTag, Url = r, Database = Database.Name }); DropOutgoingConnections(removed, instancesToDispose); } if (internalConnections.AddedDestinations.Count > 0) { var added = internalConnections.AddedDestinations.Select(r => new InternalReplication { NodeTag = _clusterTopology.TryGetNodeTagByUrl(r).NodeTag, Url = r, Database = Database.Name }); StartOutgoingConnections(added.ToList()); } _internalDestinations.Clear(); _internalDestinations.AddRange(newInternalDestinations); }
public List <ReplicationNode> GetDestinations(string myTag, string databaseName, Dictionary <string, DeletionInProgressStatus> deletionInProgress, ClusterTopology clusterTopology, RachisState state) { var list = new List <string>(); var destinations = new List <ReplicationNode>(); if (Promotables.Contains(myTag)) // if we are a promotable we can't have any destinations { return(destinations); } var nodes = Members.Concat(Rehabs); foreach (var node in nodes) { if (node == myTag) // skip me { continue; } if (deletionInProgress != null && deletionInProgress.ContainsKey(node)) { continue; } list.Add(clusterTopology.GetUrlFromTag(node)); } foreach (var promotable in Promotables) { if (deletionInProgress != null && deletionInProgress.ContainsKey(promotable)) { continue; } var url = clusterTopology.GetUrlFromTag(promotable); PredefinedMentors.TryGetValue(promotable, out var mentor); if (WhoseTaskIsIt(state, new PromotableTask(promotable, url, databaseName, mentor), null) == myTag) { list.Add(url); } } // remove nodes that are not in the raft cluster topology list.RemoveAll(url => clusterTopology.TryGetNodeTagByUrl(url).HasUrl == false); foreach (var url in list) { destinations.Add(new InternalReplication { NodeTag = clusterTopology.TryGetNodeTagByUrl(url).NodeTag, Url = url, Database = databaseName }); } return(destinations); }
public List <ReplicationNode> GetDestinations(string nodeTag, string databaseName, ClusterTopology clusterTopology, RachisState state) { var list = new List <string>(); var destinations = new List <ReplicationNode>(); if (Members.Contains(nodeTag) == false) // if we are not a member we can't have any destinations { return(destinations); } foreach (var member in Members) { if (member == nodeTag) //skip me { continue; } list.Add(clusterTopology.GetUrlFromTag(member)); } foreach (var promotable in Promotables.Concat(Rehabs)) { var url = clusterTopology.GetUrlFromTag(promotable); PredefinedMentors.TryGetValue(promotable, out var mentor); if (WhoseTaskIsIt(new PromotableTask(promotable, url, databaseName, mentor), state) == nodeTag) { list.Add(url); } } // remove nodes that are not in the raft cluster topology list.RemoveAll(url => clusterTopology.TryGetNodeTagByUrl(url).HasUrl == false); foreach (var url in list) { destinations.Add(new InternalReplication { NodeTag = clusterTopology.TryGetNodeTagByUrl(url).NodeTag, Url = url, Database = databaseName }); } return(destinations); }