/// <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; }
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)); }
/// <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."); } }