/// <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(); } } } }