예제 #1
0
        /// <summary>
        /// Create divide problem message that can be send to a task manager.
        /// </summary>
        /// <returns>Divide problem message.</returns>
        public override Message CreateMessage()
        {
            var message = new DivideProblemMessage
            {
                ComputationalNodes = Problem.NumberOfParts.Value,
                ProblemData = Problem.Data,
                ProblemInstanceId = Problem.Id,
                ProblemType = Problem.Type,
                TaskManagerId = AssigneeId
            };

            return message;
        }
예제 #2
0
        public void DivideProblemMessageXmlIsProperlySerializedAndDeserialized()
        {
            var message = new DivideProblemMessage
            {
                ComputationalNodes = 5,
                TaskManagerId = 10,
                ProblemData = new byte[] {1, 2, 3, 4, 5},
                ProblemInstanceId = 15,
                ProblemType = "Dvrp"
            };

            var serializedMessage = _serializer.Serialize(message);
            var deserializedMessage = _serializer.Deserialize(serializedMessage);

            Assert.IsInstanceOfType(deserializedMessage, typeof (DivideProblemMessage));
        }
예제 #3
0
        /// <summary>
        /// Handler for DivideProblemMessage.
        /// </summary>
        /// <param name="message">A DivideProblemMessage.</param>
        /// <exception cref="System.InvalidOperationException">
        ///     Thrown when:
        ///     - message is designated for TaskManger with different ID,
        ///     - problem type can't be divided with this TaskManager,
        ///     - dividing the problem cannot be started bacause no threads are available in thread pool.
        /// </exception>
        private void DivideProblemMessageHandler(DivideProblemMessage message)
        {
            if (Id != message.TaskManagerId)
            {
                // shouldn't ever get here - received message for other TaskManager
                throw new InvalidOperationException(
                    string.Format("TaskManager with ID={0} received message for TaskManager with ID={1}.", Id,
                        message.TaskManagerId));
            }
            Type taskSolverType;
            if (!TaskSolvers.TryGetValue(message.ProblemType, out taskSolverType))
            {
                // shouldn't ever get here - received unsolvable problem
                throw new InvalidOperationException(
                    string.Format("\"{0}\" problem type can't be divided with this TaskManager.", message.ProblemType));
            }

            var actionDescription = string.Format("Dividing problem \"{0}\"(problem instance id={1})",
                message.ProblemType, message.ProblemInstanceId);
            // should be started properly cause server sends at most as many tasks to do as count of component's threads in idle state
            var started = StartActionInNewThread(() =>
            {
                var taskSolver = (TaskSolver)Activator.CreateInstance(taskSolverType, message.ProblemData);
                taskSolver.ThrowIfError();

                var partialProblemsData = taskSolver.DivideProblem((int)message.ComputationalNodes);
                taskSolver.ThrowIfError();

                var partialProblems = new List<PartialProblemsMessage.PartialProblem>(partialProblemsData.GetLength(0));
                for (var i = 0; i < partialProblemsData.GetLength(0); i++)
                {
                    partialProblems.Add(new PartialProblemsMessage.PartialProblem
                    {
                        PartialProblemId = (ulong)i,
                        Data = partialProblemsData[i],
                        TaskManagerId = Id
                    });
                }

                var partialProblemsMessage = new PartialProblemsMessage
                {
                    ProblemType = message.ProblemType,
                    ProblemInstanceId = message.ProblemInstanceId,
                    CommonData = message.ProblemData,
                    PartialProblems = partialProblems
                };

                EnqueueMessageToSend(partialProblemsMessage);
            }, actionDescription, message.ProblemType, message.ProblemInstanceId, null);
            if (!started)
            {
                throw new InvalidOperationException(
                    "Couldn't divide problem because couldn't start new thread.");
            }
        }