/********************************************************************/ /************************** PRIVATE METHODS *************************/ /********************************************************************/ private void startMessageQueue() { SmartConsole.PrintLine("Message Queing Actived", SmartConsole.DebugLevel.Advanced); while (Active) { // should hang ArrayList socketsToRead = server.SelectForRead(); foreach (Socket socket in socketsToRead) { // NEW SENDING MESSAGE List <Message> messages = server.ReceiveMessages(socket); for (int i = 0; i < messages.Count; i++) { Message message = messages[i]; // Message was null if client disconnected if (message == null) { continue; } MessagePackage messageHandler = new MessagePackage(message, socket); lock (Queue) { Queue.Enqueue(messageHandler); } } // END NEW SENDING MESSAGE } } SmartConsole.PrintLine("Message Queing Deactived", SmartConsole.DebugLevel.Advanced); }
/// <summary> /// In this function divideProblem message is sent if there is a new task and node is has proper taskSolver. /// It returns true in case of completition of sending the message. /// </summary> /// <param name="numOfTask"></param> /// <param name="node"></param> /// <param name="messagePackage"></param> /// <returns></returns> private bool isMessageProblemDividedSent(int numOfTask, NetworkNode node, MessagePackage messagePackage ) { if (taskTracker.Tasks[numOfTask].Status == Cluster.TaskStatus.New && taskTracker.Tasks[numOfTask].Type == node.SolvableProblems[0]) { DivideProblemMessage divideProblemMessage = new DivideProblemMessage(taskTracker.Tasks[numOfTask].Type, (ulong)taskTracker.Tasks[numOfTask].ID, taskTracker.Tasks[numOfTask].BaseData, (ulong)4, (ulong)node.Id); taskTracker.Tasks[numOfTask].Status = Cluster.TaskStatus.Dividing; server.Send(messagePackage.Socket, divideProblemMessage); SmartConsole.PrintLine("Divide problem message has been sent", SmartConsole.DebugLevel.Advanced); return true; } return false; }
/*******************************************************************/ /************************ PRIVATE METHODS **************************/ /*******************************************************************/ /// <summary> /// Register is sent by every node in order to register /// to server /// </summary> /// <param name="messagePackage"></param> private void handleRegisterMessage(MessagePackage messagePackage) { RegisterMessage message = (RegisterMessage)messagePackage.Message; Socket socket = messagePackage.Socket; // If node wants to quit if (message.Deregister) { deregisterNode(message, socket); } // clean new register else if (!message.Deregister && !message.IdSpecified) { registerNewNode(message, socket); } // for backup to register existing in primary server node. else { registerExistingNode(message, socket); } }
/// <summary> /// in this function solution message with solved partial solution is sent (it checks if all subtasks of task are solved. /// It returns true in case of completition of sending the message. /// </summary> /// <param name="numberOfTask"></param> /// <param name="node"></param> /// <param name="messagePackage"></param> /// <returns></returns> private bool isMergeSolutionSent(int numberOfTask, NetworkNode node, MessagePackage messagePackage) { if (taskTracker.Tasks[numberOfTask].Status != Cluster.TaskStatus.Merging && taskTracker.Tasks[numberOfTask].Status != Cluster.TaskStatus.Merged && taskTracker.Tasks[numberOfTask].subTasks.Count != 0) { for (int j = 0; j < taskTracker.Tasks[numberOfTask].subTasks.Count; j++) { if (taskTracker.Tasks[numberOfTask].subTasks[j].Status != Cluster.TaskStatus.Solved) { return false; } } } else { return false; } if (taskTracker.Tasks[numberOfTask].Type == node.SolvableProblems[0]) { taskTracker.Tasks[numberOfTask].Status = Cluster.TaskStatus.Merging; Solution[] solutions = new Solution[taskTracker.Tasks[numberOfTask].subTasks.Count]; for (int k = 0; k < solutions.Count(); k++) { solutions[k] = new Solution(SolutionsSolutionType.Final); } for (int j = 0; j < taskTracker.Tasks[numberOfTask].subTasks.Count; j++) { solutions[j].Data = taskTracker.Tasks[numberOfTask].subTasks[j].Solutions[0].Data; } SolutionsMessage solutionMessage = new SolutionsMessage(taskTracker.Tasks[numberOfTask].Type, (ulong)taskTracker.Tasks[numberOfTask].ID, taskTracker.Tasks[numberOfTask].CommonData, solutions); server.Send(messagePackage.Socket, solutionMessage); SmartConsole.PrintLine("Solution Message has been sent to Task Manager", SmartConsole.DebugLevel.Advanced); return true; } return false; }
/// <summary> /// Status is sent by everyone as Keep-alive message /// </summary> /// <param name="messagePackage"></param> private void handleStatusMessage(MessagePackage messagePackage) { StatusMessage message = (StatusMessage)messagePackage.Message; // check what node lock (clientTracker.lockObject) { NetworkNode networkNode = clientTracker.GetNodeByID(message.Id); networkNode.LastSeen = DateTime.Now; UpdateThreadsStatus(networkNode, message); // inform backup if (networkNode.Type != RegisterType.CommunicationServer) { InformBackup(message); } //if status message was send by TaskManager than check if there are any tasks to divide or merge if (networkNode.Type == RegisterType.TaskManager) { //Response to TaskManager statusMessage ReactToTaskManagerStatusMessage(networkNode, messagePackage); } //is staty message was send by computational node than check if there are any partial problems to calculate. else if (networkNode.Type == RegisterType.ComputationalNode) { ReactToComputationalNodeStatusMessage(networkNode, messagePackage); } else { if (Server.primaryMode) { NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers); server.Send(messagePackage.Socket, response); SmartConsole.PrintLine("Sent a NoOperation Message", SmartConsole.DebugLevel.Basic); } } } }
/*******************************************************************/ /************************* PUBLIC METHODS **************************/ /*******************************************************************/ /// <summary> /// Handles the given package. /// Reads the message, changes the state of the system /// and (if needed) sends a response to the original addressee /// </summary> /// <param name="package"> /// Message to be handled /// </param> public void HandleMessage(MessagePackage package) { Message message = package.Message; lock (this) { if (message.GetType() == typeof(StatusMessage)) handleStatusMessage(package); else if (message.GetType() == typeof(RegisterMessage)) handleRegisterMessage(package); else if (message.GetType() == typeof(SolvePartialProblemsMessage)) handleSolvePartialProblemsMessage(package); else if (message.GetType() == typeof(SolutionRequestMessage)) handleSolutionRequestMessage(package); else if (message.GetType() == typeof(SolutionsMessage)) handleSolutionsMessage(package); else if (message.GetType() == typeof(SolveRequestMessage)) handleSolveRequestMessage(package); else if (message.GetType() == typeof(NoOperationMessage)) handleNoOperationMessage(package); else if (message.GetType() == typeof(RegisterResponseMessage)) handleRegisterResponsenMessage(package); else throw new NotImplementedException("Unknow message type, can't handle it."); } }
private void handleRegisterResponsenMessage(MessagePackage package) { RegisterResponseMessage message = (RegisterResponseMessage)package.Message; systemTracker.Node.Id = message.Id; systemTracker.Node.Timeout = message.Timeout; systemTracker.Node.BackupServers = message.BackupCommunicationServers; clientTracker.BackupServers = message.BackupCommunicationServers; }
private void handleNoOperationMessage(MessagePackage package) { NoOperationMessage message = (NoOperationMessage)package.Message; clientTracker.BackupServers = message.BackupCommunicationServers; SmartConsole.PrintLine("Current Backup count: " + clientTracker.BackupServers.Length, SmartConsole.DebugLevel.Basic); }
/// <summary> /// SolveRequest is sent by Computational Client /// </summary> /// <param name="messagePackage"></param> private void handleSolveRequestMessage(MessagePackage messagePackage) { SolveRequestMessage message = (SolveRequestMessage)messagePackage.Message; InformBackup(message); // if the cluster can solve this problem if (clientTracker.CanSolveProblem(message.ProblemType)) { Task task = new Task((int)systemTracker.GetNextTaskID(), message.ProblemType, message.Data); taskTracker.AddTask(task); if (Server.primaryMode) { NoOperationMessage responseNoOp = new NoOperationMessage(clientTracker.BackupServers); SolveRequestResponseMessage response = new SolveRequestResponseMessage((ulong)task.ID); List<Message> messages = new List<Message>(); messages.Add(responseNoOp); messages.Add(response); server.Send(messagePackage.Socket, messages); SmartConsole.PrintLine("Sent a SolveRequestResponse Message", SmartConsole.DebugLevel.Basic); } } else { //TODO RESPONSE MESSAGE Console.Write(" >> TM ERROR\n"); } }
/// <summary> /// this function is a response to task manager status message /// </summary> /// <param name="networkNode"></param> /// <param name="messagePackage"></param> private void ReactToTaskManagerStatusMessage(NetworkNode networkNode,MessagePackage messagePackage) { //checks if divide or merge solution message has been sent. If not than send noOperation message. bool hasMessageBeenSent = false; int numberOfAvaliableThreads = AvaliableThreadsCount(networkNode); for (int i = 0; i < taskTracker.Tasks.Count && numberOfAvaliableThreads > 0; i++) { if (isMessageProblemDividedSent(i, networkNode, messagePackage)) { hasMessageBeenSent = true; numberOfAvaliableThreads--; } } // If there are avaliable threads than try to send merge solution message for (int i = 0; i < taskTracker.Tasks.Count && numberOfAvaliableThreads > 0; i++) { if (isMergeSolutionSent(i, networkNode, messagePackage)) { hasMessageBeenSent = true; numberOfAvaliableThreads--; } } //if divideProblemMessage hasn't been sent than send noOperationMessage if (hasMessageBeenSent == false && Server.primaryMode) { NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers); server.Send(messagePackage.Socket, response); SmartConsole.PrintLine("Sent a NoOperation Message. 0 tasks to divide or 0 apropriate task managers", SmartConsole.DebugLevel.Basic); } }
/// <summary> /// SolutionRequest is sent by Computational Client /// </summary> /// <param name="messagePackage"></param> private void handleSolutionRequestMessage(MessagePackage messagePackage) { SolutionRequestMessage message = (SolutionRequestMessage)messagePackage.Message; Task task = taskTracker.GetTask((int)message.Id); SolutionsMessage solutionMessage = new SolutionsMessage(task.Type, (ulong)task.ID, task.CommonData, task.Solutions); server.Send(messagePackage.Socket, solutionMessage); if (task.Solutions[0].Type != SolutionsSolutionType.Ongoing) { taskTracker.Tasks.Remove(task); } }
/// <summary> /// SolvePartialProblem is sent by TM /// </summary> /// <param name="messagePackage"></param> private void handleSolvePartialProblemsMessage(MessagePackage messagePackage) { /* add partial tasks to subTask list in a task */ SolvePartialProblemsMessage message = (SolvePartialProblemsMessage)messagePackage.Message; InformBackup(message); Task task = taskTracker.GetTask((int)message.Id); task.Status = TaskStatus.Divided; for (int i = 0; i < message.PartialProblems.Count(); i++) { Task subTask = new Task((int)message.Id, message.ProblemType, message.PartialProblems[i].Data); subTask.Status = TaskStatus.New; task.AddSubTask(subTask); } /***********************************************/ if (Server.primaryMode) { NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers); server.Send(messagePackage.Socket, response); SmartConsole.PrintLine("Sent a NoOperation Message", SmartConsole.DebugLevel.Basic); } }
/// <summary> /// function sending PartialProblems message /// </summary> /// <param name="numOfTask"></param> /// <param name="partialList"></param> /// <param name="messagePackage"></param> /// <returns></returns> private bool SendPartialProblemsMessage(int numOfTask, List<PartialProblem> partialList, MessagePackage messagePackage) { PartialProblem[] partialProblems = new PartialProblem[partialList.Count]; for (int j = 0; j < partialList.Count; j++) { partialProblems[j] = partialList[j]; } SolvePartialProblemsMessage solvePartialProblemsMessage = new SolvePartialProblemsMessage(taskTracker.Tasks[numOfTask].Type, (ulong)taskTracker.Tasks[numOfTask].ID, taskTracker.Tasks[numOfTask].CommonData, (ulong)4, partialProblems); server.Send(messagePackage.Socket, solvePartialProblemsMessage); SmartConsole.PrintLine("Solve Partial Problems Message has been send (to Computational node). Number of subTasks." + partialList.Count, SmartConsole.DebugLevel.Advanced); return true; }
/// <summary> /// this function is a response to Computational Node status message /// </summary> /// <param name="networkNode"></param> /// <param name="messagePackage"></param> private void ReactToComputationalNodeStatusMessage(NetworkNode networkNode, MessagePackage messagePackage) { bool messageCheck = false; for (int i = 0; i < taskTracker.Tasks.Count; i++) { if (taskTracker.Tasks[i].Status == Cluster.TaskStatus.Divided && taskTracker.Tasks[i].Type == networkNode.SolvableProblems[0]) { // REMEBER TO CHECK IF THERE IS A AVALIABLE THREAD ****************************************************************************************************** // check number of avaliable threads int avaliableThreads = AvaliableThreadsCount(networkNode); List<PartialProblem> partialList = new List<PartialProblem>(); for (int j = 0; j < taskTracker.Tasks[i].subTasks.Count && avaliableThreads > 0; j++) { if (taskTracker.Tasks[i].subTasks[j].Status == Cluster.TaskStatus.New) { avaliableThreads--; partialList.Add(new PartialProblem((ulong)taskTracker.Tasks[i].ID, taskTracker.Tasks[i].subTasks[j].BaseData, (ulong)(0))); taskTracker.Tasks[i].subTasks[j].Status = Cluster.TaskStatus.Solving; // temporary solution @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } } if (partialList.Count > 0) { messageCheck = SendPartialProblemsMessage(i, partialList, messagePackage); } if (messageCheck) { break; } } } if (messageCheck == false && Server.primaryMode) { NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers); server.Send(messagePackage.Socket, response); SmartConsole.PrintLine("Sent a NoOperation Message. 0 subTasks to divide or 0 apropriate computationalNodes", SmartConsole.DebugLevel.Basic); } }
/********************************************************************/ /************************** PRIVATE METHODS *************************/ /********************************************************************/ private void startMessageQueue() { SmartConsole.PrintLine("Message Queing Actived", SmartConsole.DebugLevel.Advanced); while (Active) { // should hang ArrayList socketsToRead = server.SelectForRead(); foreach (Socket socket in socketsToRead) { // NEW SENDING MESSAGE List<Message> messages = server.ReceiveMessages(socket); for (int i = 0; i < messages.Count; i++) { Message message = messages[i]; // Message was null if client disconnected if (message == null) continue; MessagePackage messageHandler = new MessagePackage(message, socket); lock (Queue) { Queue.Enqueue(messageHandler); } } // END NEW SENDING MESSAGE } } SmartConsole.PrintLine("Message Queing Deactived", SmartConsole.DebugLevel.Advanced); }
/// <summary> /// Solutions is sent by every node to give info /// about ongoing computations or final solutions /// </summary> /// <param name="messagePackage"></param> private void handleSolutionsMessage(MessagePackage messagePackage) { SolutionsMessage message = (SolutionsMessage)messagePackage.Message; InformBackup(message); Task task = taskTracker.GetTask((int)message.Id); //IT HAS TO BE CHANGED AFTER ADDING SUBTASK ID @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (message.Solutions[0].Type == SolutionsSolutionType.Final) { task.Solutions = message.Solutions; task.Status = TaskStatus.Merged; } else { for (int i = 0; i < task.subTasks.Count; i++) { if (task.subTasks[i].Status == TaskStatus.Solving) { task.subTasks[i].Status = TaskStatus.Solved; task.subTasks[i].Solutions = message.Solutions; break; } } } if (Server.primaryMode) { NoOperationMessage response = new NoOperationMessage(clientTracker.BackupServers); server.Send(messagePackage.Socket, response); SmartConsole.PrintLine("Sent a NoOperation Message", SmartConsole.DebugLevel.Basic); } }
/*******************************************************************/ /************************* PUBLIC METHODS **************************/ /*******************************************************************/ public void Communicate(Message message) { lock (this) { while (!client.Connected) { SmartConsole.PrintLine("Lost connection, reconnecting...", SmartConsole.DebugLevel.Advanced); client.Connect(); } // Send to server client.Send(message); // Wait for response List<Message> responseMessage = client.ReceiveMessages(); for (int i = 0; i < responseMessage.Count; i++) { // handle response // This is wrong Socket, but we dont use it anyway. MessagePackage package = new MessagePackage(responseMessage[i], client.Socket); messageHandler.HandleMessage(package); } } }