Esempio n. 1
0
        /// <summary>
        /// Handler for SolutionsMessage.
        /// </summary>
        /// <param name="message">A SolutionsMessage.</param>
        /// <exception cref="System.InvalidOperationException">
        ///     Thrown when:
        ///     - problem type can't be merged with this TaskManager,
        ///     - merging the problem cannot be started bacause no threads are available in thread pool.
        /// </exception>
        private void SolutionsMessageHandler(SolutionsMessage message)
        {
            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 merged with this TaskManager.", message.ProblemType));
            }

            var actionDescription = string.Format("Merging partial problems \"{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(() =>
            {
                ulong totalComputationsTime = 0;
                var timeoutOccured = false;
                var solutionsData = new byte[message.Solutions.Count][];
                for (var i = 0; i < message.Solutions.Count; i++)
                {
                    var solution = message.Solutions[i];

                    if (solution.Type != SolutionsMessage.SolutionType.Partial)
                        throw new InvalidOperationException(
                            string.Format("Received non-partial solution({0})(partial problem id={1}).",
                                solution.Type, solution.PartialProblemId));
                    totalComputationsTime += solution.ComputationsTime;
                    timeoutOccured |= solution.TimeoutOccured;
                    solutionsData[i] = solution.Data;
                }

                var taskSolver = (TaskSolver)Activator.CreateInstance(taskSolverType, message.CommonData);
                taskSolver.ThrowIfError();

                // measure time using DateTime cause StopWatch is not guaranteed to be thread safe
                var start = DateTime.UtcNow;
                var finalSolutionData = taskSolver.MergeSolution(solutionsData);
                var stop = DateTime.UtcNow;

                taskSolver.ThrowIfError();
                totalComputationsTime += (ulong)((stop - start).TotalMilliseconds);

                var finalSolution = new SolutionsMessage.Solution
                {
                    Type = SolutionsMessage.SolutionType.Final,
                    ComputationsTime = totalComputationsTime,
                    TimeoutOccured = timeoutOccured,
                    Data = finalSolutionData
                };
                var finalSolutionMessage = new SolutionsMessage
                {
                    ProblemType = message.ProblemType,
                    ProblemInstanceId = message.ProblemInstanceId,
                    CommonData = message.CommonData,
                    Solutions = new List<SolutionsMessage.Solution> { finalSolution }
                };

                EnqueueMessageToSend(finalSolutionMessage);
            }, actionDescription, message.ProblemType, message.ProblemInstanceId, null);
            if (!started)
            {
                throw new InvalidOperationException(
                    "Couldn't merge partial solutions because couldn't start new thread.");
            }
        }
Esempio n. 2
0
        public void SolutionsMessageXmlIsProperlySerializedAndDeserialized()
        {
            var s = new SolutionsMessage.Solution
            {
                ComputationsTime = 5,
                Data = new byte[] {1, 2, 3},
                PartialProblemId = 10,
                TimeoutOccured = true,
                Type = SolutionsMessage.SolutionType.Final
            };

            var message = new SolutionsMessage
            {
                CommonData = new byte[] {1, 2, 3},
                ProblemInstanceId = 5,
                ProblemType = "Dvrp",
                Solutions = new List<SolutionsMessage.Solution> {s}
            };

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

            Assert.IsInstanceOfType(deserializedMessage, typeof (SolutionsMessage));
        }
Esempio n. 3
0
        /// <summary>
        /// Create solutions message that can be send to a task manager in order to request the merge.
        /// </summary>
        /// <returns>Solutions message.</returns>
        public override Message CreateMessage()
        {
            var msgPartialSolutions = new List<SolutionsMessage.Solution>(PartialSolutions.Count);

            foreach (var ps in PartialSolutions)
            {
                var msgPs = new SolutionsMessage.Solution
                {
                    ComputationsTime = ps.ComputationsTime,
                    Data = ps.Data,
                    PartialProblemId = ps.PartialProblem.Id,
                    TimeoutOccured = ps.TimeoutOccured,
                    Type = SolutionsMessage.SolutionType.Partial
                };
                msgPartialSolutions.Add(msgPs);
            }

            var problem = PartialSolutions[0].PartialProblem.Problem;

            var message = new SolutionsMessage
            {
                CommonData = problem.CommonData,
                ProblemInstanceId = problem.Id,
                ProblemType = problem.Type,
                Solutions = msgPartialSolutions
            };

            return message;
        }