// Master tells the worker to fail itself and stabilizes the system internal static bool fail(string url) { if (isFailedServer(url)) { return(false); } int id = getAvailableID(url); if (isFreezedServer(url)) { freezedServers.Remove(id); } failedServers.Add(id, url); string failed_sucessorURL = getWorkerSucessor(id); string failed_predecessorURL = getWorkerPredecessor(id); IMasterWorker failed_sucessor = (IMasterWorker)Activator.GetObject( typeof(IMasterWorker), failed_sucessorURL + "MasterWorker"); IMasterWorker failed_predecessor = (IMasterWorker)Activator.GetObject( typeof(IMasterWorker), failed_predecessorURL + "MasterWorker"); // Na posicao original dos available trocar o url pelo sucessor availableServers[id] = failed_sucessorURL; //Set sucessor of failed_predecessor to failed_sucessor -> Problema de concorrencia entre estas 2 operções? failed_predecessor.setSucessor(failed_sucessorURL); //Tell the sucessor to substitute the failed server failed_sucessor.substituteFailedServer(); //Tell the sucessor to fetch the original data from the failed_predecessor and put it in his the list of updates failed_sucessor.fetch_data(failed_predecessorURL); IMasterWorker datastore = (IMasterWorker)Activator.GetObject( typeof(IMasterWorker), url + "MasterWorker"); // Last thing to do is change the state, so that the library can continue working datastore.fail(); return(true); }
// Sets the detected url to failed internal static string setFailedServer(string url) { // simple sanity check if (!failedServers.ContainsValue(url)) { // if the server was available do the following if (availableServers.ContainsValue(url)) { lock (availableServers) { int id = getAvailableID(url); int sucessorID = id + 1; if (sucessorID >= availableServers.Count) { sucessorID = 0; } int predecessorID = id - 1; if (predecessorID < 0) { predecessorID = availableServers.Count; } string predecessorURL = availableServers[predecessorID]; string sucessorURL = availableServers[sucessorID]; string failedURL = availableServers[id]; IMasterWorker sucessor = (IMasterWorker)Activator.GetObject(typeof(IMasterWorker), sucessorURL + "MasterWorker"); IMasterWorker predecessor = (IMasterWorker)Activator.GetObject(typeof(IMasterWorker), predecessorURL + "MasterWorker"); IMasterWorker failed = (IMasterWorker)Activator.GetObject(typeof(IMasterWorker), failedURL + "MasterWorker"); availableServers[id] = sucessorURL; // same as availableServers[successorID] sucessor.setPredecessor(predecessorURL); predecessor.setSucessor(sucessorURL); sucessor.substituteFailedServer(); failed.fail(); failedServers.Add(id, url); return(sucessorURL); } } else if (freezedServers.ContainsValue(url)) { lock (freezedServers) { int id = getFreezeID(url); int sucessorID = id + 1; if (sucessorID >= freezedServers.Count) { sucessorID = 0; } int predecessorID = id - 1; if (predecessorID < 0) { predecessorID = freezedServers.Count; } string predecessorURL = freezedServers[predecessorID]; string sucessorURL = freezedServers[sucessorID]; string failedURL = freezedServers[id]; IMasterWorker sucessor = (IMasterWorker)Activator.GetObject(typeof(IMasterWorker), sucessorURL + "MasterWorker"); IMasterWorker predecessor = (IMasterWorker)Activator.GetObject(typeof(IMasterWorker), predecessorURL + "MasterWorker"); IMasterWorker failed = (IMasterWorker)Activator.GetObject(typeof(IMasterWorker), failedURL + "MasterWorker"); // the server was both in available and freezed servers availableServers[id] = sucessorURL; sucessor.setPredecessor(predecessorURL); predecessor.setSucessor(sucessorURL); sucessor.substituteFailedServer(); failed.fail(); freezedServers.Remove(id); failedServers.Add(id, url); return(sucessorURL); } } } return(null); }