/// <summary> /// Call if one worker is available /// </summary> /// <param name="workerUrl">worker url</param> /// <returns></returns> public bool FinishProcessing(string workerUrl, WorkStatus workerStatus) { TestFrozenC(); jobsAssigmentMutex.WaitOne(); foreach (WorkStatus iWorkStatus in jobsAssigment) { if (iWorkStatus.getWorkerId() == workerStatus.getWorkerId() && iWorkStatus.getBeginIndex() == workerStatus.getBeginIndex()) { iWorkStatus.setLastModification(workerStatus.getLastModification()); iWorkStatus.setNumberLinesComputed(workerStatus.getNumberLinesComputed()); iWorkStatus.setTotalNumberOfLines(workerStatus.getTotalNumberLines()); iWorkStatus.setWorkerId(workerStatus.getWorkerId()); //Console.WriteLine("FINISH " + workerStatus.getWorkerId()); break; } } jobsAssigmentMutex.ReleaseMutex(); availableWorkerToJobMutex.WaitOne(); bool exists = availableWorkerToJob.Contains(workerUrl); availableWorkerToJobMutex.ReleaseMutex(); if (!exists) { availableWorkerToJobMutex.WaitOne(); availableWorkerToJob.Add(workerUrl); availableWorkerToJobMutex.ReleaseMutex(); queueWorkersSemaphore.Release(1); } return(true); }
// ============================================= // Threads Section // ============================================= /// <summary> /// Async method to keep tracking of alive workers /// </summary> public void IsAliveAsync() { while (!jobDone) { TestFrozenC(); //Is alive interval Thread.Sleep(2000); //Create a copy of the workersUrl workersIDUrlMutex.WaitOne(); HashSet <KeyValuePair <int, string> > clonedWorkersUrl = new HashSet <KeyValuePair <int, string> >(workersIDUrl); workersIDUrlMutex.ReleaseMutex(); jobsAssigmentMutex.WaitOne(); HashSet <WorkStatus> clonedJobAssigments = new HashSet <WorkStatus>(jobsAssigment); jobsAssigmentMutex.ReleaseMutex(); foreach (KeyValuePair <int, string> worker in clonedWorkersUrl) { //Get the worker IWorker workerObj = (IWorker)Activator.GetObject(typeof(IWorker), worker.Value); try { //Retrive the workStatus of the worker WorkStatus workerStatus = workerObj.IsAlive(clonedWorkersUrl, clonedJobAssigments); //Update the workStatus of that worker jobsAssigmentMutex.WaitOne(); foreach (WorkStatus iWorkStatus in jobsAssigment) { if (iWorkStatus.getWorkerId() == workerStatus.getWorkerId() && iWorkStatus.getBeginIndex() == workerStatus.getBeginIndex()) { iWorkStatus.setLastModification(workerStatus.getLastModification()); iWorkStatus.setNumberLinesComputed(workerStatus.getNumberLinesComputed()); iWorkStatus.setTotalNumberOfLines(workerStatus.getTotalNumberLines()); iWorkStatus.setWorkerId(workerStatus.getWorkerId()); //Console.WriteLine("isalive" + workerStatus.getWorkerId()); break; } } jobsAssigmentMutex.ReleaseMutex(); //TODO: test if the worker is too slow } catch (Exception) { //The worker didn't anwser Console.WriteLine("***************" + worker.Value + "dead"); //Remove the worker from the workersList workersIDUrlMutex.WaitOne(); workersIDUrl.Remove(worker); workersIDUrlMutex.ReleaseMutex(); //Removes all the works not done and assigned to it jobsAssigmentMutex.WaitOne(); foreach (WorkStatus iWorkStatus in jobsAssigment) { if (iWorkStatus.getWorkerId() == worker.Key && !iWorkStatus.isWorkCompleted()) { iWorkStatus.removeWorker(); } } jobsAssigmentMutex.ReleaseMutex(); //Remove from available worker availableWorkerToJobMutex.WaitOne(); availableWorkerToJob.Remove(worker.Value); availableWorkerToJobMutex.ReleaseMutex(); } } } }
/// <summary> /// Async method to run job /// </summary> /// <param name="className"></param> /// <param name="dllCode"></param> /// <param name="beginIndex"></param> /// <param name="endIndex"></param> /// <param name="clientUrl"></param> /// <param name="jobTrackerUrl"></param> public void RunAsyncJob(string className, byte[] dllCode, long beginIndex, long endIndex, string clientUrl) { // Get Input Split from client myWorkerStatus.changeStatus(WorkStatus.Status.GettingInput); IClient clientObj = (IClient)Activator.GetObject(typeof(IClient), clientUrl); TestFrozenW(); //Test if it is frozen string input = clientObj.getInputSplit(ownId, beginIndex, endIndex); // Fetch dll myWorkerStatus.changeStatus(WorkStatus.Status.FetchingInput); Assembly assembly = Assembly.Load(dllCode); foreach (Type type in assembly.GetTypes()) { if (type.IsClass == true) { if (type.FullName.EndsWith("." + className)) { try { //Update Status myWorkerStatus.setLastModification(DateTime.Now); myWorkerStatus.setTotalNumberOfLines(input.Count(x => x == '\n') + 1); myWorkerStatus.setNumberLinesComputed(0); //Start invoking the methods myWorkerStatus.changeStatus(WorkStatus.Status.Computing); object ClassObj = Activator.CreateInstance(type); StringBuilder sb = new StringBuilder(); using (StringReader sr = new StringReader(input)) { String inputLine; while ((inputLine = sr.ReadLine()) != null) { delayMutex.WaitOne(); if (this.threadDelay > 0) { Thread.Sleep(this.threadDelay * 1000); this.threadDelay = 0; } delayMutex.ReleaseMutex(); // Dynamically Invoke the method object[] args = new object[] { inputLine }; //FREEZEW - Not Able to Compute TestFrozenW(); object resultObject = type.InvokeMember("Map", BindingFlags.Default | BindingFlags.InvokeMethod, null, ClassObj, args); myWorkerStatus.setNumberLinesComputed(myWorkerStatus.getNumberLinesComputed() + 1); foreach (KeyValuePair <string, string> resultPair in (IList <KeyValuePair <string, string> >)resultObject) { sb.Append(resultPair.Key); sb.Append(":"); sb.Append(resultPair.Value); sb.Append(Environment.NewLine); } } } //Test if the work is still valid IWorker jobTracker = (IWorker)Activator.GetObject(typeof(IWorker), currentJobTracker); //FREEZEW - Not Able to Communicate with outside TestFrozenW(); bool splitValid = jobTracker.isSplitValid(ownId, beginIndex); if (splitValid) { myWorkerStatus.changeStatus(WorkStatus.Status.SendingOutput); //FREEZEW - Not Able to Communicate with outside TestFrozenW(); // Send processed split to the client with my Id and the Result clientObj.sendProcessedSplit(ownId, sb.ToString()); } //FREEZEW - Not Able to Communicate with outside TestFrozenW(); jobTracker.FinishProcessing(ownUrl, myWorkerStatus); myWorkerStatus.changeStatus(WorkStatus.Status.Idle); } catch (Exception e) { System.Console.WriteLine("IMPOSSIBLE TO CONNECT TO JOBTRACKER ON: " + currentJobTracker); /*System.Console.WriteLine("[WORKER_SERVICES_ERROR1:RUN_ASYNC_JOB] Could not invoke method."); * System.Console.WriteLine("========================="); * System.Console.WriteLine(e.StackTrace); * System.Console.WriteLine("========================="); * System.Console.WriteLine(e.GetType()); * System.Console.WriteLine("========================="); * System.Console.WriteLine(e.Message); * System.Console.WriteLine("========================="); * System.Console.WriteLine(e.InnerException.Message); * System.Console.WriteLine("========================="); * System.Console.WriteLine(e.InnerException.StackTrace);*/ } } } } }