/// <summary> /// Mwtoda serializuje obiekty pochodne MessageObject /// </summary> /// <param name="message">Obiekt do serializacji</param> /// <param name="type">Typ wiadomości</param> /// <returns></returns> public byte[] SerilizeMessageObject(MessageObject message, Type type) { XmlSerializer serializer = new XmlSerializer(type); StringBuilder sb = new StringBuilder(); StringWriter stringWriter = new StringWriter(sb); serializer.Serialize(stringWriter, message); return System.Text.Encoding.UTF8.GetBytes(sb.ToString().Replace("utf-16", "utf-8")); }
/// <summary> /// Aktualizuje informację o TM i CN. Sprawdza czy jest dla nich nowe zadanie i jeśli znajdzie, odsyła. /// </summary> /// <param name="obj">Status TM/CN</param> /// <returns></returns> private MessageObject UpdateAndGiveData(MessageObject obj) { MessageObject response = null; Status status = obj as Status; lock (lockObj) { Node node = taskManagers.Find(item => item.Id == status.Id); if (node == null) node = computationalNodes.Find(item => item.Id == status.Id); if (node != null) { node.Update(status.Threads); UpdateTemporaryProblems(node.TemporaryProblems); if (node.GetAvailableThreads() > 0) { if (node.GetType() == typeof(TaskManager)) { Problem partialP = problems.Find(t => t.Status == ProblemStatus.PartiallySolved && node.SolvableProblems.Contains(t.ProblemType)); if (partialP != null) { partialP.Status = ProblemStatus.WaitingForSolutions; List<Solution> solutions = new List<Solution>(); node.TemporaryProblems.Add(new TempProblem(partialP.Id, ProblemStatus.WaitingForSolutions, null)); foreach (var pp in partialP.PartialProblems) { solutions.Add(new Solution(pp.TaskId, pp.TimeoutOccured, SolutionType.Partial, pp.ComputationsTime, pp.Data)); } response = new Solutions(partialP.ProblemType, partialP.Id, partialP.CommonData, solutions); return response; } Problem newP = problems.Find(t => t.Status == ProblemStatus.New && node.SolvableProblems.Contains(t.ProblemType)); if (newP != null) { newP.Status = ProblemStatus.WaitingForDivision; node.TemporaryProblems.Add(new TempProblem(newP.Id, ProblemStatus.WaitingForDivision, null)); ulong computationalNodesCount = (ulong)computationalNodes.Sum(t => t.GetAvailableThreads()); response = new DivideProblem(newP.ProblemType, newP.Id, newP.Data, computationalNodesCount); return response; } } else // ComputationalNode { Problem dividedP = problems.Find(t => t.Status == ProblemStatus.Divided && node.SolvableProblems.Contains(t.ProblemType)); if (dividedP != null) { List<CommunicationXML.PartialProblem> pp = dividedP.GetPartialProblemListToSolve(node.GetAvailableThreads()); response = new SolvePartialProblems(dividedP.ProblemType, dividedP.Id, dividedP.CommonData, dividedP.SolvingTimeout, pp); List<TempPartial> ppnums = new List<TempPartial>(); foreach(var x in pp) { ppnums.Add(new TempPartial(x.TaskId, PartialProblemStatus.Sended)); } node.TemporaryProblems.Add(new TempProblem(dividedP.Id, dividedP.Status, ppnums)); return response; } } } } } return response; }
/// <summary> /// Publiczny konstruktor obiektu XmlParser /// </summary> /// <param name="data">Dane Xml jako tablica bajtów, które chcemy zmienić na obiekt jednego z typów pochodnych MessageObject</param> public XMLParser(byte [] data) { //xmlMessage = StringToBytesConverter.GetString(data); xmlMessage = System.Text.Encoding.UTF8.GetString(data); System.Console.WriteLine(xmlMessage); System.Console.WriteLine(); object result; if(null != (result = TryDeserilize(typeof(Register)))) { messageType = MessageTypes.Register; message = (Register)result; return; } if (null != (result = TryDeserilize(typeof(RegisterResponse)))) { messageType = MessageTypes.RegisterResponse; message = (RegisterResponse)result; return; } if(null != (result = TryDeserilize(typeof(SolutionRequest)))) { messageType = MessageTypes.SolutionRequest; message = (SolutionRequest)result; return; } if(null != (result = TryDeserilize(typeof(DivideProblem)))) { messageType = MessageTypes.DivideProblem; message = (DivideProblem)result; return; } if(null != (result = TryDeserilize(typeof(SolveRequestResponse)))) { messageType = MessageTypes.SolveRequestResponse; message = (SolveRequestResponse)result; return; } if(null != (result = TryDeserilize(typeof(SolveRequest)))) { messageType = MessageTypes.SolveRequest; message = (SolveRequest)result; return; } if(null != (result = TryDeserilize(typeof(SolvePartialProblems)))) { messageType = MessageTypes.SolvePartialProblems; message = (SolvePartialProblems)result; return; } if(null != (result = TryDeserilize(typeof(Status)))) { messageType = MessageTypes.Status; message = (Status)result; return; } if(null !=(result = TryDeserilize(typeof(Solutions)))) { messageType = MessageTypes.Solutions; message = (Solutions)result; return; } throw new ArgumentException("data can not be deserialized"); }
/// <summary> /// Wysyłanie rozwiązania do CC. /// </summary> /// <param name="obj">SolutionRequest</param> private Solutions SendSolution(MessageObject obj) { Solutions response = null; SolutionRequest request = obj as SolutionRequest; lock (lockObj) { Problem p = problems.Find(x => x.Id == request.Id); if (p != null) { List<Solution> solutions = new List<Solution>(); if (p.Status == ProblemStatus.Solved) { solutions.Add(new Solution(p.TimeoutOccured, SolutionType.Final, p.ComputationsTime, p.Data)); // Usuwanie wysłanego problemu z listy. problems.Remove(p); } else { foreach (var s in p.PartialProblems) { solutions.Add( new Solution(s.TaskId, s.TimeoutOccured, s.PartialProblemStatus == PartialProblemStatus.Solved ? SolutionType.Partial : SolutionType.Ongoing, s.ComputationsTime, s.Data)); } if (solutions.Count == 0) solutions.Add(Solution.GetEmptySolution()); } response = new Solutions(p.ProblemType, p.Id, p.CommonData, solutions); } } return response; }
/// <summary> /// Dodawanie nowego problemu do listy. /// </summary> /// <param name="obj">Nowy problem</param> /// <returns></returns> private SolveRequestResponse RegisterNewProblem(MessageObject obj) { SolveRequest req = obj as SolveRequest; SolveRequestResponse response = null; lock (lockObj) { Problem p = new Problem(req.ProblemType, req.Data, req.SolvingTimeout); problems.Add(p); response = new SolveRequestResponse(p.Id); } return response; }
/// <summary> /// Rejestracja nowego Computational Node lub Task Manager /// </summary> /// <param name="obj">Informacje o nowym TM/CN</param> /// <returns></returns> private RegisterResponse RegisterNewNode(MessageObject obj) { Register reg = obj as Register; RegisterResponse response; lock (lockObj) { switch (reg.Type) { case NodeType.TaskManager: TaskManager tm = new TaskManager(reg.SolvableProblems, reg.ParallelThreads); taskManagers.Add(tm); response = new RegisterResponse(tm.Id, timeout); break; case NodeType.ComputationalNode: ComputationalNode cn = new ComputationalNode(reg.SolvableProblems, reg.ParallelThreads); computationalNodes.Add(cn); response = new RegisterResponse(cn.Id, timeout); break; default: response = null; break; } } return response; }
/// <summary> /// Pobiera częściowe i całkowite rozwiązania. /// </summary> /// <param name="obj">Solutions</param> private void GetSolutions(MessageObject obj) { Solutions solutions = obj as Solutions; lock (lockObj) { Problem p = problems.Find(x => x.Id == solutions.Id && x.ProblemType == solutions.ProblemType); if (p != null) { p.SetSolutions(solutions.SolutionsList); } } }
/// <summary> /// Odbiera podzielone dane od TM. /// </summary> /// <param name="obj">SolvePartialProblems</param> private void GetDividedProblem(MessageObject obj) { SolvePartialProblems partialProblems = obj as SolvePartialProblems; lock (lockObj) { Problem p = problems.Find(x => x.Id == partialProblems.Id && x.ProblemType == partialProblems.ProblemType); if (p != null && p.Status == ProblemStatus.WaitingForDivision) { p.SetPartialProblems(partialProblems.CommonData, partialProblems.PartialProblems); } } }