public bool join(int txId, String url) { Console.WriteLine("[Join]: {0} is participant in Tx{1}", url, txId); MyTransaction tr; //TODO testar se a transacao e servidor existem tr = (MyTransaction)clientTransactions[txId]; DataServerInfo dsInfo = null; foreach (DataServerInfo ds in dataServers) { if (ds.URL.Equals(url)) { dsInfo = ds; } } if (!tr.Participants.Contains(dsInfo)) { tr.Participants.Add(dsInfo); return(true); } else { return(false); } }
// Data server register from data server itself public void Register(string address) { DataServerInfo dsi = new DataServerInfo(address); Monitor.Enter(onlineDataServers); onlineDataServers.Add(dsi); Monitor.Exit(onlineDataServers); for (int i = 0; i < msi.GetLength(0); i++) { MetadataServerInfo mi = msi[i]; if (mi != null && mi.port != this.metadataPort) { try { MetadataMessageService metadataServer = (MetadataMessageService)Activator.GetObject(typeof(MetadataMessageService), "tcp://localhost:" + mi.port + "/MessageService"); metadataServer.RegisterDataReplica(dsi.address); } catch (RemotingException e) { onlineMS[mi.getID(base_port)] = false; msi[i] = null; } catch (SocketException e) { onlineMS[mi.getID(base_port)] = false; msi[i] = null; } } } // Console.WriteLine("DataServer at " + address + " has registered."); }
// Data server register replication public void RegisterDataReplica(string address) { DataServerInfo dsi = new DataServerInfo(address); Monitor.Enter(onlineDataServers); onlineDataServers.Add(dsi); Monitor.Exit(onlineDataServers); // Console.WriteLine("DataServer at " + address + " has registered (replica received from principal metadata server)."); }
public override bool Equals(Object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } DataServerInfo dsInfo = (DataServerInfo)obj; return(this.Id == dsInfo.Id); }
/// <summary> /// <para>Gets the instance of the /// <see cref="Microsoft.Hpc.Scheduler.Session.Data.DataClient" /> class that has the specified /// string identifier.</para> /// </summary> /// <param name="dataClientId"> /// <para>A /// <see cref="System.String" /> that specifies the identifier for the /// <see cref="Microsoft.Hpc.Scheduler.Session.Data.DataClient" /> object that you want to get.</para> /// </param> /// <returns> /// <para>A <see cref="Microsoft.Hpc.Scheduler.Session.Data.DataClient" /> object that has the specified identifier.</para> /// </returns> public static DataClient GetDataClient(string dataClientId) { Microsoft.Hpc.Scheduler.Session.Data.Utility.ValidateDataClientId(dataClientId); if (!inService) { throw new InvalidOperationException(SR.ServiceContextIsNotAvailable); } using (NonHARegistry registry = new NonHARegistry()) { if (registry.CheckIfNonDomain().GetAwaiter().GetResult()) { return(GetNonDomainDataClient(dataClientId)); } } if (SoaHelper.IsOnAzure()) { // if it is running in Azure, just talk to DataProxy // Note: headnode name will not be used. return(DataClient.Open("dataproxy", dataClientId)); } lock (lockDataServerInfoInitialized) { if (!bDataServerInfoInitialized) { string strDataServerInfo = Environment.GetEnvironmentVariable(Microsoft.Hpc.Scheduler.Session.Internal.Constant.SoaDataServerInfoEnvVar); if (!string.IsNullOrEmpty(strDataServerInfo)) { dataServerInfo = new DataServerInfo(strDataServerInfo); } else { logger.TraceEvent(TraceEventType.Error, 0, "[ServiceContext] .GetDataClient: no data server configured"); DataServerInfoConfigException = new DataException(DataErrorCode.NoDataServerConfigured, SR.NoDataServerConfigured); } bDataServerInfoInitialized = true; } } if (dataServerInfo != null) { string containerPath = DataContainerHelper.OpenDataContainer(dataServerInfo, dataClientId); return(new DataClient(dataClientId, containerPath, /*readOnly = */ true)); } else { throw DataServerInfoConfigException; } }
/// <summary> /// Generate data container store path from data server info and data container name /// </summary> /// <param name="dsInfo">data server info</param> /// <param name="containerName">data container name</param> /// <returns>store path of the data container</returns> private static string GenerateDataContainerPath(DataServerInfo dsInfo, string containerName) { // Note: below code snippet is copied from data service code. int hashValue = 0; for (int i = 0; i < containerName.Length; i++) { hashValue = (hashValue * 37) + containerName[i]; } hashValue = Math.Abs(hashValue); hashValue = hashValue % MaxSubDirectoryCount; string containerPath = Path.Combine(dsInfo.AddressInfo, hashValue.ToString()); containerPath = Path.Combine(containerPath, containerName); return(containerPath); }
public IPadInt CreatePadInt(int uid) { try { Console.WriteLine("[CREATE] Client wants to create PadInt with id " + uid); if (!padInts.Contains(uid)) { if (dataServers.Count == 0) { Console.WriteLine("[!CREATE] Error: There are no available DataServers"); Console.WriteLine("---"); return(null); } DataServerInfo dServer = (DataServerInfo)dataServers[indexLastServer]; while (dServer.remoteServer.isFail) { Console.WriteLine("[CREATE] DataServer " + dServer.Name /*dServer.remoteServer.name*/ + " is set to [Fail]: Passing his turn on Round Robin"); indexLastServer = (indexLastServer + 1) % dataServers.Count; // salta um índice dServer = (DataServerInfo)dataServers[indexLastServer]; } IPadInt obj = dServer.remoteServer.store(uid); // obj nao vem nunca a null porque controlámos isso nos ifs anteriores... // Round Robin: indexLastServer = (indexLastServer + 1) % dataServers.Count; padInts.Add(uid, dServer); MyPadInt myPadInt = new MyPadInt(uid, obj); addPadInt(myPadInt); Console.WriteLine("[CREATE] PadInt " + uid + " stored on " + dServer.Name /*dServer.remoteServer.name*/); Console.WriteLine("---"); return(obj); } else { Console.WriteLine("[!CREATE] Error: PadInt " + uid + " already exists."); Console.WriteLine("---"); return(null); } } catch (RemotingException re) { Console.WriteLine("[CreatePadInt]:\n" + re); throw new OperationException("CreatePadInt operation at PadInt " + uid + "failed."); } }
/// <summary> /// Open data container locally. /// Note: this method is introduced to avoid invoking OpenDataClient call onto data service. /// This is a shortcut for ServiceContext use only. /// </summary> /// <param name="dsInfo">data server info</param> /// <param name="containerName">data container name</param> /// <returns>data container store path</returns> public static string OpenDataContainer(DataServerInfo dsInfo, string containerName) { if (dsInfo == null) { throw new DataException(DataErrorCode.NoDataServerConfigured, string.Empty); } Utility.ValidateDataServerInfo(dsInfo); try { string containerPath = GenerateDataContainerPath(dsInfo, containerName); FileDataContainer.CheckReadPermission(containerPath); return(containerPath); } catch (DataException e) { e.DataServer = dsInfo.AddressInfo; e.DataClientId = containerName; throw; } }
public void registerNewPrimaryServer(String newServerUrl, int Id) { Console.WriteLine(" Register New Primary Server "); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = @"..\..\..\DataServer\bin\Debug\DataServer.exe"; startInfo.Arguments = (Id + " " + UrlToPort(newServerUrl)); Process p = Process.Start(startInfo); Thread.Sleep(TimeSpan.FromSeconds(2)); DataServerInfo dsInfoFound = null; DataServerInfo dsInfoOld = new DataServerInfo(Id); foreach (DataServerInfo ds in dataServers) { if (ds.Equals(dsInfoOld)) { dsInfoFound = ds; } } if (dsInfoFound == null) { //nothing to do here, server does not exists return; } try { //Creating DataServer Reference IDataServer remoteServerRef = (IDataServer)Activator.GetObject(typeof(IDataServer), newServerUrl); dsInfoFound.remoteServer = remoteServerRef; dsInfoFound.URL = remoteServerRef.URL; dsInfoFound.Name = remoteServerRef.name; // <----- Atenção aqui (RTT), ha alternativa? } catch (RemotingException re) { Console.WriteLine("[registerNewPrimaryServer]:\n" + re); return; } this.clearCache(); Console.WriteLine("[registerNewPrimaryServer]: Operation Succeed!\n"); }
public int registerServer(String url) { foreach (DataServerInfo server in dataServers) { if (server.URL.Equals(url)) { return(-1); } } // obter referencia remota e registar servidor String[] aux = url.Split(':'); String[] aux2 = aux[2].Split('/'); int primary = Convert.ToInt32(aux2[0]); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = @"..\..\..\DataServer\bin\Debug\DataServer.exe"; startInfo.Arguments = (primary + 1) + " " + primary; Process p = Process.Start(startInfo); try { IDataServer remoteServer = (IDataServer)Activator.GetObject(typeof(IDataServer), url); //DataServerInfo serverInfo = new DataServerInfo(url, remoteServer, remoteServer.name,id); // <----- Atenção aqui (RTT), ha alternativa? // Quero criar um DataServerInfo cujo Id seja a sua porta... não o id do master (que é sempre zero) DataServerInfo serverInfo = new DataServerInfo(url, remoteServer, remoteServer.name, primary); // <----- Atenção aqui (RTT), ha alternativa? dataServers.Add(serverInfo); Console.WriteLine("Server " + serverInfo.Name /*remoteServer.name*/ + " registered."); Console.WriteLine("---"); lock (this) { Interlocked.Increment(ref id); } return(id); } catch (RemotingException re) { Console.WriteLine("[registerNewServer]:\n" + re); return(-1); } }
// Se o server a que esse objecto pertence estiver em Freeze ou Fail, faz sentido // devolvermos o objecto em cache? Não estamos a violar o comportamento suposto? // // mais: ao devolver o url ao client, nao devemos tambem ir buscar o objecto e por na cache? // // Se a cache contem o PadInt // retornamos PadInt // Caso contrario // retornamos url public PadIntInfo AccessPadInt(int uid) { try { Console.WriteLine("[ACCESS] Client requests PadInt with id " + uid); if (padIntsCache.Contains(new MyPadInt(uid))) { int index = padIntsCache.IndexOf(new MyPadInt(uid)); MyPadInt myObj = (MyPadInt)padIntsCache[index]; IPadInt obj = myObj.PadInt; PadIntInfo padIntInfo = new PadIntInfo(obj); Console.WriteLine("[ACCESS] PadInt " + uid + " returned from the cache. "); Console.WriteLine("---"); return(padIntInfo); } else if (padInts.Contains(uid)) { DataServerInfo dServer = (DataServerInfo)padInts[uid]; PadIntInfo padIntInfo = new PadIntInfo(dServer.URL); Console.WriteLine("[ACCESS] Returned " + dServer.Name /*dServer.remoteServer.name*/ + "'s URL, to further access PadInt " + uid + "."); Console.WriteLine("---"); IPadInt padInt = dServer.remoteServer.load(uid); MyPadInt myPadInt = new MyPadInt(uid, padInt); addPadInt(myPadInt); return(padIntInfo); } else //PadInt nao existe { Console.WriteLine("[!ACCESS] Error: PadInt " + uid + " does not exist."); Console.WriteLine("---"); return(null); } } catch (RemotingException re) { Console.WriteLine("[AccessPadInt]:\n" + re); throw new OperationException("AccessPadInt operation at PadInt " + uid + "failed."); } }
public bool TxCommit(int txId) { int faulty = 0; // Auxiliar ArrayList to save the DataServer to whom we successfully issued the canCommit ArrayList pServers = new ArrayList(); Console.WriteLine("[TxCommit] Client request"); if (!clientTransactions.ContainsKey(txId)) { throw new TxException(txId, "Transaction with id " + txId + "does not exists!"); } try { lock (this) { MyTransaction t = (MyTransaction)clientTransactions[txId]; _myCommitDecision = true; for (int i = 0; i < t.Participants.Count; ++i) { faulty = i; DataServerInfo ds = (DataServerInfo)t.Participants[i]; _myCommitDecision = _myCommitDecision && ds.remoteServer.canCommit(t.TxId); pServers.Add(t.Participants[i]); } // Compara o tamanho dos arrays para saber se foi possivel fazer o canCommit a todos // se não for igual, aos que fizeram canCommit manda agora abortar e retorna false if (pServers.Count != t.Participants.Count) { foreach (DataServerInfo pt in pServers) { pt.remoteServer.doAbort(txId); } return(false); } if (_myCommitDecision) { Console.WriteLine("[TxCommit] Every Server voted Yes"); // try to commit infinite times foreach (DataServerInfo p in t.Participants) { while (true) { p.remoteServer.doCommit(t.TxId); break; } } } else { Console.WriteLine("[TxCommit] Some Server voted No."); _myCommitDecision = false; TxAbort(txId); } } Console.WriteLine("---"); return(true); } catch (RemotingException re) { Console.WriteLine("[TxCommit]:\n" + re); throw new TxException(txId, "TxCommit transaction with id " + txId + "failed. canCommit voting failed."); } catch (Exception) { Console.WriteLine("TxCommit can not complete. One participant DataServer is failed."); Console.WriteLine("The faulty DataServer will be removed from the participants of the Transaction."); Console.WriteLine("The current transaction will be aborted!"); MyTransaction t = (MyTransaction)clientTransactions[txId]; t.Participants.RemoveAt(faulty); TxAbort(txId); throw new OperationException("TxCommit can not be executed. Server does not respond. This transaction was automatically aborted!"); } }