/// <summary> /// Sends a request into the network /// </summary> /// <returns>The awaitable task.</returns> /// <param name="req">The request to transmit.</param> public static void TransmitRequest(PendingNetworkRequest req) { if (_connector == null) { lock (_lock) if (_connector == null) { _connector = new NetworkClientConnector(NameServerHostname, NameServerPort); _connectorTask = _connector.RunAsync(); } } _connector.Requests.Write(req); }
/// <summary> /// Writes a <see cref="CoCoL.Network.PendingNetworkRequest" /> to the connection. /// </summary> /// <returns>The awaitable task.</returns> /// <param name="req">The request to write.</param> public Task WriteAsync(PendingNetworkRequest req) { return(m_writeRequests.WriteAsync(req)); }
/// <summary> /// The process that reads data from the underlying stream and parses it into a <see cref="CoCoL.Network.PendingNetworkRequest" />. /// </summary> /// <returns>The awaitable task.</returns> /// <param name="client">The <see cref="System.Net.Sockets.TcpClient"/> to read data from.</param> /// <param name="stream">The stream to read data from.</param> /// <param name="channel">The channel to write requests to.</param> /// <param name="selfid">A string used to identify this process in logs</param> private static async Task ReaderProcess(TcpClient client, Stream stream, IWriteChannelEnd <PendingNetworkRequest> channel, string selfid) { try { var buffer = new byte[SMALL_MESSAGE_SIZE]; var json = new Newtonsoft.Json.JsonSerializer(); using (client) using (stream) using (channel) { while (true) { LOG.DebugFormat("{0}: Waiting for data from stream", selfid); await ForceReadAsync(stream, buffer, 0, 8); LOG.DebugFormat("{0}: Not waiting for data from stream", selfid); var streamlen = BitConverter.ToUInt64(buffer, 0); if (streamlen > MAX_MESSAGE_SIZE) { throw new Exception("Perhaps too big data?"); } await ForceReadAsync(stream, buffer, 0, 2); var headlen = BitConverter.ToUInt16(buffer, 0); if (headlen > buffer.Length || headlen > streamlen) { throw new Exception("Perhaps too big data?"); } await ForceReadAsync(stream, buffer, 0, headlen); RequestHeader header; using (var ms = new MemoryStream(buffer, 0, headlen)) using (var sr = new StreamReader(ms)) using (var jr = new Newtonsoft.Json.JsonTextReader(sr)) header = json.Deserialize <RequestHeader>(jr); LOG.DebugFormat("{4}: Got {0} - {1} request with {2} bytes from {3}", header.RequestID, header.RequestType, streamlen, client.Client.RemoteEndPoint, selfid); await ForceReadAsync(stream, buffer, 0, 8); var payloadlen = BitConverter.ToUInt64(buffer, 0); if (payloadlen > MAX_MESSAGE_SIZE || payloadlen > streamlen - headlen) { throw new Exception("Perhaps too big data?"); } object payload = null; if (header.PayloadClassName != null) { var bf = payloadlen <= (ulong)buffer.Length ? buffer : new byte[payloadlen]; await ForceReadAsync(stream, bf, 0, (int)payloadlen); var objtype = Type.GetType(header.PayloadClassName); if (objtype == null) { throw new ArgumentException(string.Format("Unable to determine the target type to create for {0}", header.PayloadClassName)); } using (var ms = new MemoryStream(bf, 0, (int)payloadlen)) using (var sr = new StreamReader(ms)) using (var jr = new Newtonsoft.Json.JsonTextReader(sr)) payload = json.Deserialize(jr, objtype); } var pnrq = new PendingNetworkRequest( header.ChannelID, Type.GetType(header.ChannelDataType), header.RequestID, header.SourceID, header.Timeout, header.RequestType, payload, header.NoOffer ); LOG.DebugFormat("{2}: Forwarding {0} - {1} request", header.RequestID, header.RequestType, selfid); await channel.WriteAsync(pnrq); LOG.DebugFormat("{2}: Forwarded {0} - {1} request", header.RequestID, header.RequestType, selfid); } } } catch (Exception ex) { if (!ex.IsRetiredException()) { LOG.Error("Crashed network client reader side", ex); throw; } else { LOG.Info("Stopped network client reader"); } } }
/// <summary> /// Initializes a new instance of the <see cref="CoCoL.Network.TwoPhaseNetworkHandler"/> class. /// </summary> /// <param name="pnr">The pending network request.</param> /// <param name="nwc">The network client.</param> public TwoPhaseNetworkHandler(PendingNetworkRequest pnr, NetworkClient nwc) { m_pnr = pnr; m_nwc = nwc; }