public string WhoseTaskIsIt( RachisState state, IDatabaseTask task, Func <string> getLastResponsibleNode) { if (state == RachisState.Candidate || state == RachisState.Passive) { return(null); } var mentorNode = task.GetMentorNode(); if (mentorNode != null) { if (Members.Contains(mentorNode)) { return(mentorNode); } } var lastResponsibleNode = getLastResponsibleNode?.Invoke(); if (lastResponsibleNode != null) { return(lastResponsibleNode); } var topology = new List <string>(Members); topology.AddRange(Promotables); topology.AddRange(Rehabs); topology.Sort(); if (topology.Count == 0) { return(null); // this is probably being deleted now, no one is able to run tasks } var key = task.GetTaskKey(); while (true) { var index = (int)Hashing.JumpConsistentHash.Calculate(key, topology.Count); var entry = topology[index]; if (Members.Contains(entry)) { return(entry); } topology.RemoveAt(index); if (topology.Count == 0) { return(null); // all nodes in the topology are probably in rehab } // rehash so it will likely go to a different member in the cluster key = Hashing.Mix(key); } }
public string WhoseTaskIsIt( RachisState state, IDatabaseTask task, Func <string> getLastResponsibleNode) { if (state == RachisState.Candidate || state == RachisState.Passive) { return(null); } var mentorNode = task.GetMentorNode(); if (mentorNode != null) { if (Members.Contains(mentorNode)) { return(mentorNode); } } var lastResponsibleNode = getLastResponsibleNode?.Invoke(); if (lastResponsibleNode != null) { return(lastResponsibleNode); } var topology = new List <string>(Members); topology.AddRange(Promotables); topology.AddRange(Rehabs); topology.Sort(); if (task.IsResourceIntensive() && Members.Count > 1) { // if resource intensive operation, we don't want to have it on the first node of the database topology return(FindNodeForIntensiveOperation(task.GetTaskKey(), topology)); } return(FindNode(task.GetTaskKey(), topology)); }
public string WhoseTaskIsIt(IDatabaseTask task, bool inPassiveState) { if (inPassiveState) { return(null); } var topology = new List <string>(Members); topology.AddRange(Promotables); topology.AddRange(Rehabs); topology.Sort(); if (topology.Count == 0) { return(null); // this is probably being deleted now, no one is able to run tasks } var key = task.GetTaskKey(); while (true) { var index = (int)Hashing.JumpConsistentHash.Calculate(key, topology.Count); var entry = topology[index]; if (Members.Contains(entry)) { return(entry); } topology.RemoveAt(index); if (topology.Count == 0) { return(null); // all nodes in the topology are probably in rehab } // rehash so it will likely go to a different member in the cluster key = Hashing.Mix(key); } }