/// <summary> /// Connect one CRA vertex to another, via pre-defined endpoints. We contact the "from" vertex /// to initiate the creation of the link. /// </summary> /// <param name="fromVertexName">Name of the vertex from which connection is being made</param> /// <param name="fromEndpoint">Name of the endpoint on the fromVertex, from which connection is being made</param> /// <param name="toVertexName">Name of the vertex to which connection is being made</param> /// <param name="toEndpoint">Name of the endpoint on the toVertex, to which connection is being made</param> /// <param name="direction">Which vertex initiates the connection</param> /// <returns>Status of the Connect operation</returns> public CRAErrorCode Connect(string fromVertexName, string fromEndpoint, string toVertexName, string toEndpoint, ConnectionInitiator direction) { // Tell from vertex to establish connection // Send request to CRA instance // Check that vertex and endpoints are valid and existing if (!_vertexTableManager.ExistsVertex(fromVertexName) || !_vertexTableManager.ExistsVertex(toVertexName)) { // Check for sharded vertices List <int> fromVertexShards, toVertexShards; if (!_vertexTableManager.ExistsShardedVertex(fromVertexName, out fromVertexShards)) { return(CRAErrorCode.VertexNotFound); } if (!_vertexTableManager.ExistsShardedVertex(toVertexName, out toVertexShards)) { return(CRAErrorCode.VertexNotFound); } return(ConnectSharded(fromVertexName, fromVertexShards, fromEndpoint, toVertexName, toVertexShards, toEndpoint, direction)); } // Make the connection information stable _connectionTableManager.AddConnection(fromVertexName, fromEndpoint, toVertexName, toEndpoint); // We now try best-effort to tell the CRA instance of this connection CRAErrorCode result = CRAErrorCode.Success; VertexTable _row; try { // Get instance for source vertex _row = direction == ConnectionInitiator.FromSide ? VertexTable.GetRowForVertex(_vertexTable, fromVertexName) : VertexTable.GetRowForVertex(_vertexTable, toVertexName); } catch { Console.WriteLine("Unable to find active instance with vertex. On vertex activation, the connection should be completed automatically."); return(result); } try { if (_localWorker != null) { if (_localWorker.InstanceName == _row.InstanceName) { return(_localWorker.Connect_InitiatorSide(fromVertexName, fromEndpoint, toVertexName, toEndpoint, direction == ConnectionInitiator.ToSide)); } } // Send request to CRA instance TcpClient client = null; // Get address and port for instance, using row with vertex = "" var row = VertexTable.GetRowForInstance(_vertexTable, _row.InstanceName); // Get a stream connection from the pool if available Stream stream; if (!TryGetSenderStreamFromPool(row.Address, row.Port.ToString(), out stream)) { client = new TcpClient(row.Address, row.Port); client.NoDelay = true; stream = client.GetStream(); if (SecureStreamConnectionDescriptor != null) { stream = SecureStreamConnectionDescriptor.CreateSecureClient(stream, _row.InstanceName); } } if (direction == ConnectionInitiator.FromSide) { stream.WriteInt32((int)CRATaskMessageType.CONNECT_VERTEX_INITIATOR); } else { stream.WriteInt32((int)CRATaskMessageType.CONNECT_VERTEX_INITIATOR_REVERSE); } stream.WriteByteArray(Encoding.UTF8.GetBytes(fromVertexName)); stream.WriteByteArray(Encoding.UTF8.GetBytes(fromEndpoint)); stream.WriteByteArray(Encoding.UTF8.GetBytes(toVertexName)); stream.WriteByteArray(Encoding.UTF8.GetBytes(toEndpoint)); result = (CRAErrorCode)stream.ReadInt32(); if (result != 0) { Console.WriteLine("Connection was logically established. However, the client received an error code from the connection-initiating CRA instance: " + result); } else { // Add/Return a stream connection to the pool TryAddSenderStreamToPool(row.Address, row.Port.ToString(), stream); } } catch { Console.WriteLine("The connection-initiating CRA instance appears to be down or could not be found. Restart it and this connection will be completed automatically"); } return(result); }
internal CRAErrorCode InstantiateVertex(string instanceName, string vertexName, string vertexDefinition, object vertexParameter, bool sharded) { var procDefRow = VertexTable.GetRowForVertexDefinition(_vertexTable, vertexDefinition); string blobName = vertexName + "-" + instanceName; // Serialize and write the vertex parameters to a blob CloudBlobContainer container = _blobClient.GetContainerReference("cra"); container.CreateIfNotExistsAsync().Wait(); var blockBlob = container.GetBlockBlobReference(vertexDefinition + "/" + blobName); CloudBlobStream blobStream = blockBlob.OpenWriteAsync().GetAwaiter().GetResult(); byte[] parameterBytes = Encoding.UTF8.GetBytes( SerializationHelper.SerializeObject(vertexParameter)); blobStream.WriteByteArray(parameterBytes); blobStream.Close(); // Add metadata var newRow = new VertexTable(instanceName, vertexName, vertexDefinition, "", 0, procDefRow.VertexCreateAction, blobName, false, sharded); TableOperation insertOperation = TableOperation.InsertOrReplace(newRow); _vertexTable.ExecuteAsync(insertOperation).Wait(); CRAErrorCode result = CRAErrorCode.Success; // Send request to CRA instance VertexTable instanceRow; try { instanceRow = VertexTable.GetRowForInstance(_vertexTable, instanceName); // Get a stream connection from the pool if available Stream stream; if (!TryGetSenderStreamFromPool(instanceRow.Address, instanceRow.Port.ToString(), out stream)) { TcpClient client = new TcpClient(instanceRow.Address, instanceRow.Port); client.NoDelay = true; stream = client.GetStream(); if (SecureStreamConnectionDescriptor != null) { stream = SecureStreamConnectionDescriptor.CreateSecureClient(stream, instanceName); } } stream.WriteInt32((int)CRATaskMessageType.LOAD_VERTEX); stream.WriteByteArray(Encoding.UTF8.GetBytes(vertexName)); stream.WriteByteArray(Encoding.UTF8.GetBytes(vertexDefinition)); stream.WriteByteArray(Encoding.UTF8.GetBytes(newRow.VertexParameter)); result = (CRAErrorCode)stream.ReadInt32(); if (result != 0) { Console.WriteLine("Vertex was logically loaded. However, we received an error code from the hosting CRA instance: " + result); } // Add/Return stream connection to the pool TryAddSenderStreamToPool(instanceRow.Address, instanceRow.Port.ToString(), stream); } catch { Console.WriteLine("The CRA instance appears to be down. Restart it and this vertex will be instantiated automatically"); } return(result); }