public void NodeIsDeregisteredAfterTimeout() { uint communicationTimeout = 1; uint checkInterval = 1; var stopwatch = new Stopwatch(); var deregistrationEventLock = new AutoResetEvent(false); _overseer = new ComponentOverseer(communicationTimeout, checkInterval); _overseer.Deregistration += (o, e) => { deregistrationEventLock.Set(); }; _overseer.StartMonitoring(); var solvableProblems = new List <string> { "dvrp" }; ComponentInfo computationalNode = new SolverNodeInfo(ComponentType.ComputationalNode, solvableProblems, 5); _overseer.TryRegister(computationalNode); stopwatch.Start(); Assert.IsTrue(_overseer.IsRegistered(computationalNode.ComponentId.Value)); deregistrationEventLock.WaitOne(1000 * (int)(communicationTimeout + checkInterval + 1)); stopwatch.Stop(); Assert.IsFalse(_overseer.IsRegistered(computationalNode.ComponentId.Value)); Assert.IsTrue((ulong)stopwatch.ElapsedMilliseconds >= communicationTimeout); _overseer.StopMonitoring(); }
public void AllTypesOfNodesAreProperlyRegistered() { _overseer = new ComponentOverseer(5, 5); var solvableProblems = new List <string> { "dvrp" }; var serverInfo = new ServerInfo { IpAddress = "127.0.0.1", Port = 9135 }; ComponentInfo taskManager = new SolverNodeInfo(ComponentType.TaskManager, solvableProblems, 5); ComponentInfo computationalNode = new SolverNodeInfo(ComponentType.ComputationalNode, solvableProblems, 5); ComponentInfo backupServer = new BackupServerInfo(serverInfo, 5); Assert.IsNull(taskManager.ComponentId); Assert.IsNull(computationalNode.ComponentId); Assert.IsNull(backupServer.ComponentId); _overseer.TryRegister(taskManager); _overseer.TryRegister(computationalNode); _overseer.TryRegister(backupServer); Assert.IsTrue(_overseer.IsRegistered(taskManager.ComponentId.Value)); Assert.IsTrue(_overseer.IsRegistered(computationalNode.ComponentId.Value)); Assert.IsTrue(_overseer.IsRegistered(backupServer.ComponentId.Value)); }
/// <summary> /// Handle registration message. /// </summary> /// <param name="msg">Register message.</param> /// <param name="metadata">Information about data and the TCP connection it came from.</param> /// <returns>List of response messages.</returns> private List <Message> HandleMessage(RegisterMessage msg, TcpDataProviderMetadata metadata) { ComponentInfo componentInfo; switch (msg.ComponentType) { case ComponentType.CommunicationServer: var serverInfo = new ServerInfo { IpAddress = metadata.SenderAddress.Address.ToString(), Port = (ushort)metadata.SenderAddress.Port }; componentInfo = new BackupServerInfo(serverInfo, msg.ParallelThreads); break; case ComponentType.ComputationalNode: case ComponentType.TaskManager: componentInfo = new SolverNodeInfo(msg.ComponentType, msg.SolvableProblems, msg.ParallelThreads); break; default: throw new InvalidOperationException("Invalid component type registration (" + msg.ComponentType + ")."); } _componentOverseer.TryRegister(componentInfo); var responseMsg = new RegisterResponseMessage { AssignedId = componentInfo.ComponentId.Value, BackupServers = CreateBackupList(), CommunicationTimeout = _componentOverseer.CommunicationTimeout }; return(new List <Message> { responseMsg }); }
/// <summary> /// Try get and assign work to the specified component. /// </summary> /// <param name="node">Node to assign work to.</param> /// <param name="work">Assigned work.</param> /// <returns>Whether there is any work compatible with the component.</returns> public bool TryAssignWork(SolverNodeInfo node, out Work work) { var type = node.ComponentType; var nodeId = node.ComponentId.Value; if (type == ComponentType.TaskManager) { var partialSolutionsToMerge = _partialSolutions.Values.Where(ps => ps.State == PartialSolution.PartialSolutionState.AwaitingMerge && node.SolvableProblems.Contains(ps.PartialProblem.Problem.Type)) .ToList(); if (partialSolutionsToMerge.Count != 0) { var problemId = partialSolutionsToMerge[0].PartialProblem.Problem.Id; var solutionsToAssign = partialSolutionsToMerge.Where(ps => ps.PartialProblem.Problem.Id == problemId) .ToList(); foreach (var ps in solutionsToAssign) { ps.State = PartialSolution.PartialSolutionState.BeingMerged; ps.MergingNodeId = nodeId; } work = new MergeWork(nodeId, solutionsToAssign); var e = new WorkAssignmentEventArgs { AssigneeId = nodeId, Work = work }; if (WorkAssignment != null) { WorkAssignment(this, e); } return(true); } var problemToDivide = _problems.Values.FirstOrDefault(p => p.State == Problem.ProblemState.AwaitingDivision && node.SolvableProblems.Contains(p.Type)); if (problemToDivide != null) { problemToDivide.State = Problem.ProblemState.BeingDivided; problemToDivide.DividingNodeId = nodeId; var availableThreads = CountAvailableSolvingThreads(problemToDivide.Type); work = new DivisionWork(nodeId, problemToDivide, (ulong)availableThreads); var e = new WorkAssignmentEventArgs { AssigneeId = nodeId, Work = work }; if (WorkAssignment != null) { WorkAssignment(this, e); } return(true); } work = null; return(false); } if (type == ComponentType.ComputationalNode) { var availableThreads = node.ThreadInfo.Count(ts => ts.State == ThreadStatus.ThreadState.Idle); var partialProblemsToCompute = _partialProblems.Values.Where(pp => pp.State == PartialProblem.PartialProblemState.AwaitingComputation && node.SolvableProblems.Contains(pp.Problem.Type)); if (availableThreads == 0 || !partialProblemsToCompute.Any()) { work = null; return(false); } var problemId = partialProblemsToCompute.First().Problem.Id; var problemsToAssign = new List <PartialProblem>(availableThreads); foreach (var pp in partialProblemsToCompute) { if (availableThreads == 0) { break; } if (pp.Problem.Id == problemId) { pp.State = PartialProblem.PartialProblemState.BeingComputed; pp.ComputingNodeId = nodeId; problemsToAssign.Add(pp); availableThreads--; } } work = new ComputationWork(nodeId, problemsToAssign); var e = new WorkAssignmentEventArgs { AssigneeId = nodeId, Work = work }; if (WorkAssignment != null) { WorkAssignment(this, e); } return(true); } throw new InvalidOperationException(); }
public bool TryAssignWork(SolverNodeInfo node, out Work work) { throw new NotImplementedException(); }