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));
        }
Example #3
0
        /// <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
            });
        }
Example #4
0
        /// <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();
        }
Example #5
0
 public bool TryAssignWork(SolverNodeInfo node, out Work work)
 {
     throw new NotImplementedException();
 }