static void Main(string[] args) { /************ Create node object ************/ RegisterType type = RegisterType.TaskManager; byte parallelThreads = 5; string[] problems = { "DVRP"}; NetworkNode node = new NetworkNode(type, parallelThreads, problems); //NetworkNode node = new NetworkNode(); /************ Setup connection ************/ string inputLine = ""; foreach (string arg in args) inputLine += arg + " "; InputParser inputParser = new InputParser(inputLine); inputParser.ParseInput(); IPAddress address = inputParser.Address; int port = inputParser.Port; SmartConsole.PrintLine("I'm a " + node.Type, SmartConsole.DebugLevel.Advanced); NetworkClient client = new NetworkClient(address, port); /************ Setup Logic modules ************/ // system tracker SystemTracker systemTracker = new SystemTracker(node); MessageHandler messageHandler = new MessageHandler(systemTracker, client); MessageProcessor messageProcessor = new MessageProcessor(messageHandler, client, node); node.MessageProcessor = messageProcessor; /************ Init all threads ************/ for (int i = 0; i < parallelThreads; i++) { node.TaskThreads[i] = new TaskThread(i, problems[0], messageProcessor, (int)node.Id); } /************ Register ************/ client.Connect(); SmartConsole.PrintLine("Sending Register message", SmartConsole.DebugLevel.Advanced); messageProcessor.Communicate(node.ToRegisterMessage()); KeepAliveTimer keepAliveTimer = new KeepAliveTimer(messageProcessor, systemTracker); /************ Start Logic modules ************/ keepAliveTimer.Start(); Object mutex = new Object(); // TODO Thread pool waiting lock (mutex) { Monitor.Wait(mutex); } }
/******************************************************************/ /************************** CONSTRUCTORS **************************/ /******************************************************************/ public SystemTracker(NetworkNode node) { nextClientId = 1; Timeout = 2; Node = node; }
/// <summary> /// function counting avaliable number of threads /// </summary> /// <param name="node"></param> /// <returns></returns> private int AvaliableThreadsCount(NetworkNode node){ int threadCount = 0; foreach(TaskThread th in node.TaskThreads){ if (th.StatusThread.State == global::Communication.MessageComponents.StatusThreadState.Idle) threadCount++; } return threadCount; }
/// <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; }
/******************************************************************/ /************************** CONSTRUCTORS **************************/ /******************************************************************/ /// <summary> /// Creates KeepAliveTimer /// </summary> /// <param name="messageProcessor"></param> /// /// <param name="systemTracker"></param> public KeepAliveTimer(MessageHandler messageHandler, NetworkClient networkClient, NetworkServer server, SystemTracker systemTracker, NetworkNode node, ClientTracker clientTracker, Object backupBlockade) { this.messageHandler = messageHandler; this.client = networkClient; this.server = server; this.systemTracker = systemTracker; this.node = node; this.clientTracker = clientTracker; this.backupBlockade = backupBlockade; // TODO Magic numbers this.timer = new System.Timers.Timer((systemTracker.Timeout * 1000) / 2); this.timer.Elapsed += keepAlive; Active = false; }
/// <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> /// Adds a network node to the list of clients /// </summary> /// <param name="node"></param> public void AddNode(NetworkNode node) { switch (node.Type) { case RegisterType.CommunicationServer: backupServersList.Add(node); BackupCommunicationServer bserver = new BackupCommunicationServer(node.Address.ToString(), node.Port); AddBackupServer(bserver); break; case RegisterType.ComputationalNode: compNodes.Add(node); break; case RegisterType.TaskManager: taskManagers.Add(node); break; } }
/******************************************************************/ /************************** CONSTRUCTORS **************************/ /******************************************************************/ public ClientSystemTracker(NetworkNode node) { this.Node = node; }
static void Main(string[] args) { RegisterType type = RegisterType.ComputationalClient; byte parallelThreads = 5; string[] problems = { "DVRP" }; SolveRequestMessage solveRequestMessage = new SolveRequestMessage(); string inputLine = ""; foreach (string arg in args) inputLine += arg + " "; InputParser inputParser = new InputParser(inputLine); inputParser.ParseInput(); IPAddress address = inputParser.Address; int port = inputParser.Port; NetworkNode node = new NetworkNode(type, parallelThreads, problems) { Timeout = CLIENT_REQUEST_FREQUENCY }; SmartConsole.PrintLine("ComputationalClient starting work", SmartConsole.DebugLevel.Advanced); NetworkClient client = new NetworkClient(address, port); for (; ; ) { /*************** Register *****************/ doWork = true; SmartConsole.PrintLine("Type in a file path", SmartConsole.DebugLevel.Advanced); String filePath = Console.ReadLine(); solveRequestMessage = loadDataFromDisc(filePath); /****** setup logic modules *****************/ SystemTracker systemTracker = new SystemTracker(node); MessageHandler messageHandler = new MessageHandler(systemTracker, client); MessageProcessor messageProcessor = new MessageProcessor(messageHandler, client, node); KeepAliveTimer keepAliveTimer = new KeepAliveTimer(messageProcessor, systemTracker); messageHandler.keepAliveTimer = keepAliveTimer; node.MessageProcessor = messageProcessor; /************ send solve request *****************/ client.Connect(); messageProcessor.Communicate(solveRequestMessage); COMP_TIME = DateTime.Now; while (doWork) { Thread.Sleep(1000); } /*Object mutex = new Object(); lock (mutex) { Monitor.Wait(mutex); }*/ } }
/// <summary> /// Register new node - Primary server job /// </summary> private void registerNewNode(RegisterMessage message, Socket socket) { // Place holder, have to fetch info from the System. ulong id = systemTracker.GetNextClientID(); uint timeout = (uint)systemTracker.Timeout; SmartConsole.PrintLine("Adding new Node", SmartConsole.DebugLevel.Advanced); NetworkNode node = new NetworkNode(message.Type, id, timeout, message.ParallelThreads, message.SolvableProblems, clientTracker.BackupServers); node.LastSeen = DateTime.Now; // Backup Server if (node.Type == RegisterType.CommunicationServer) { // update Node IPAddress address = (socket.RemoteEndPoint as IPEndPoint).Address; int port = (ushort)Server.PRIMARY_PORT; node.Address = address; // TODO hack if(clientTracker.BackupServers.Length == 1) port = (ushort)Server.PRIMARY_PORT2; node.Port = (ushort)port; } // Add the node to system clientTracker.AddNode(node); RegisterResponseMessage response = new RegisterResponseMessage(id, timeout, clientTracker.BackupServers); server.Send(socket, response); RegisterMessage backUpmessage = new RegisterMessage(message.Type, message.ParallelThreads, message.SolvableProblems); backUpmessage.Id = id; InformBackup(backUpmessage); }
/// <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); } }
/// <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); } }
public ConsoleManager(NetworkClient client, NetworkNode node) { this.client = client; this.node = node; }
/******************************************************************/ /******************* PROPERTIES, PRIVATE FIELDS *******************/ /******************************************************************/ /******************************************************************/ /************************** CONSTRUCTORS **************************/ /******************************************************************/ public SystemTracker(NetworkNode node) : base(node) { }
private bool registerExistingNode(RegisterMessage message, Socket socket) { NetworkNode node = new NetworkNode(message.Type, message.Id, (uint)systemTracker.Timeout, message.ParallelThreads, message.SolvableProblems, clientTracker.BackupServers); IPAddress address = (socket.RemoteEndPoint as IPEndPoint).Address; int port = (ushort)Server.PRIMARY_PORT; // TODO hack if (clientTracker.BackupServers.Length == 1) port = (ushort)Server.PRIMARY_PORT2; node.Address = address; node.Port = (ushort)port; // Dont inform backup about it self // It comes naturally in NoOperation message if (node.Type == RegisterType.CommunicationServer && (server.Address.ToString().Equals(address.ToString()) && server.Port == port)) return false; SmartConsole.PrintLine("Backup adding existing node", SmartConsole.DebugLevel.Advanced); clientTracker.AddNode(node); return true; }
private static void registerToServer(NetworkClient client, NetworkNode node) { Console.Write(" >> Press enter to connect to server... \n"); Console.ReadLine(); Console.Write(" >> Client connecting to server... " + client.Address + ":" + client.Port + "\n"); Console.Write(" >> \n\n"); client.Connect(); RegisterMessage registerMessage = node.ToRegisterMessage(); Console.Write(" >> Sending Register message... \n\n"); client.Send(registerMessage); Console.Write(" >> Waiting for response... \n\n"); Message response = client.Receive(); Console.Write(" >> The response is: \n\n" + response.ToString() + "\n\n"); }
/// <summary> /// function updating status of each thread /// </summary> /// <param name="node"></param> /// <param name="message"></param> private void UpdateThreadsStatus(NetworkNode node, StatusMessage message){ for (int i = 0; i < node.TaskThreads.Count(); i++) { node.TaskThreads[i].StatusThread.State = message.Threads[i].State; } }
public void InitiateBackup(IPAddress myAddress, int myPort, IPAddress masterAddress, int masterPort) { SmartConsole.PrintHeader("Starting backup server"); SmartConsole.PrintLine("Address: " + myAddress.ToString() + ":" + myPort, SmartConsole.DebugLevel.Advanced); // Create overall system tracker SystemTracker systemTracker = new SystemTracker(); // Create list of all clients ClientTracker clientTracker = new ClientTracker(); // Task Tracker TaskTracker taskTracker = new TaskTracker(); // Start network connection NetworkServer server = new NetworkServer(myAddress, myPort); // Create messageHandler MessageHandler messageHandler = new MessageHandler(systemTracker, clientTracker, taskTracker, server); // Start message queue MessageQueue messageQueue = new MessageQueue(server); // Start Message processor CommunicationServer.MessageCommunication.MessageProcessor messageProcessor = new CommunicationServer.MessageCommunication.MessageProcessor(messageQueue, messageHandler); // blockade to block untill server is switched to primary mode Object backupBlockade = new Object(); server.Open(); messageQueue.Start(); messageProcessor.Start(); /********************* REGISTER AS NORMAL CLIENT *********************/ RegisterType type = RegisterType.CommunicationServer; NetworkNode node = new NetworkNode(type); systemTracker.Node = node; NetworkClient client = new NetworkClient(masterAddress, masterPort); client.Connect(); SmartConsole.PrintLine("Sending Register message...", SmartConsole.DebugLevel.Advanced); CommunicationServer.MessageCommunication.KeepAliveTimer keepAliveTimer = new CommunicationServer.MessageCommunication.KeepAliveTimer(messageHandler, client, server, systemTracker, node, clientTracker, backupBlockade); keepAliveTimer.Communicate(node.ToRegisterMessage()); /********************* START COMMUNICATING WITH PRIMARY SERVER *********************/ SmartConsole.PrintLine("Backup Server starting work", SmartConsole.DebugLevel.Advanced); keepAliveTimer.Start(); // This will hold untill server is switched to primary mode lock (backupBlockade) { Monitor.Wait(backupBlockade); } /********************* SWITCH TO PRIMARY SERVER *********************/ SmartConsole.PrintHeader("SWITCHING TO PRIMARY"); Server.primaryMode = true; client.Disconnect(); clientTracker.RefreshTimeout(); // Start measuring timeout clientTracker.StartTimeout(); // Start console manager ConsoleManager consoleManager = new ConsoleManager(server); consoleManager.Start(); }