/// <summary> /// Handle solution request message. /// </summary> /// <param name="msg">Solution request 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(SolutionRequestMessage msg, TcpDataProviderMetadata metadata) { var solution = _workManager.GetSolution(msg.ProblemInstanceId); var problem = _workManager.GetProblem(msg.ProblemInstanceId); Message response; if (solution != null) { problem = solution.Problem; var msgSolution = new SolutionsMessage.Solution { ComputationsTime = solution.ComputationsTime, Data = solution.Data, TimeoutOccured = solution.TimeoutOccured, Type = SolutionsMessage.SolutionType.Final }; response = new SolutionsMessage { CommonData = problem.CommonData, ProblemInstanceId = problem.Id, ProblemType = problem.Type, Solutions = new List <SolutionsMessage.Solution> { msgSolution } }; } else if (problem != null) { var msgSolution = new SolutionsMessage.Solution { ComputationsTime = _workManager.GetComputationsTime(problem.Id), TimeoutOccured = false, Type = SolutionsMessage.SolutionType.Ongoing }; response = new SolutionsMessage { CommonData = problem.CommonData, ProblemInstanceId = problem.Id, ProblemType = problem.Type, Solutions = new List <SolutionsMessage.Solution> { msgSolution } }; } else { response = new ErrorMessage { ErrorType = ErrorType.ExceptionOccured, ErrorText = "The specified problem id is unknown to the system." }; } return(new List <Message> { response }); }
/// <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."); } }
private SolutionsMessage MergeSolutions(SolutionsMessage oldSolutionsMessage, SolutionsMessage newSolutionsMessage) { for (int i = 0; i < newSolutionsMessage.Solutions.Length; i++) { var newSolution = newSolutionsMessage.Solutions[i]; if (newSolution == null) { throw new Exception("Could solutions is null " + newSolution.TaskId + ", problemId: " + newSolutionsMessage.Id); } var oldSolutions = oldSolutionsMessage.Solutions.ToList(); oldSolutions.AddRange(newSolutionsMessage.Solutions); oldSolutionsMessage.Solutions = oldSolutions.ToArray(); } return(oldSolutionsMessage); }
private void ThreadBackgroundWork() { SolutionRequestMessage srm = new SolutionRequestMessage() { Id = this.problemId }; SolutionsMessage sm = null; String message = String.Empty; double len = 0; string ttt; while (sm == null) { //this.potwierdzenie.Text += "\n\nAsking for Final solution... "; string str = "\nAsking for Final solution... "; this.potwierdzenie.Dispatcher.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { str }); message = this.computationalClient.SendSolutionRequest(srm); if (message != String.Empty) { switch (bn.GetMessageName(message)) { case "Solutions": var serializer = new ComputationSerializer <SolutionsMessage>(); sm = serializer.Deserialize(message); foreach (var solution in sm.Solutions) { if (solution.Type == SolutionType.Final) { //str = "\n\nFinal solution: " + System.Text.Encoding.UTF8.GetString(solution.Data); //len = DynamicVehicleRoutingProblem.DVRPPartialSolution.Parse2FinalSolLenght(System.Text.Encoding.UTF8.GetString(solution.Data)); DVRP.Solutions.FinalSolution finalSolution = (DVRP.Solutions.Solution.ToSolution(solution.Data)).ToFinalSolution(); ttt = finalSolution.ToString(); this.potwierdzenie.Dispatcher.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { "\n\n Path lenght: " + ttt }); this.potwierdzenie.Dispatcher.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { "\n SOLVED!!! \n SOLVED!!!" }); break; } } sm = null; break; case "Other...?": break; default: break; } if (len != 0) { break; } } else { //str = "\n\n Message empty"; //this.potwierdzenie.Dispatcher.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { str }); } str = " Computing..."; this.potwierdzenie.Dispatcher.Invoke(new UpdateTextCallback(this.UpdateText), new object[] { str }); Thread.Sleep(10000); } }