private void UdpReceiveThread(IPEndPoint multicastGroupAddress) { Tracing.Trace("@UdpReceiveThread"); IPEndPoint from = multicastGroupAddress; MessageHeader header = default(MessageHeader); //int count = 0; this.startCommunicatingEvent.WaitOne(); while (true) { byte[] bytes = this.udpClient.Receive(ref from); Tracing.Trace("Recv"); MessageHeader.ReadHeaderFromBuffer(bytes, 0, ref header, this.HeaderSerializer); //Console.Error.WriteLine("UdpReceiveThread: got {0} bytes from {1}. Sequence number = {2}, count = {3}", bytes.Length, from, header.SequenceNumber, count++); SerializedMessage message = new SerializedMessage(0, header, new RecvBuffer(bytes, MessageHeader.SizeOf, bytes.Length)); bool success = this.AttemptDelivery(message, 0); Debug.Assert(success); } }
private bool TryReadNextMessage() { MessageHeader nextMessageHeader = default(MessageHeader); int bytesRead = this.consumeStream.Read(this.rereadMessageHeaderBuffer, 0, this.rereadMessageHeaderBuffer.Length); if (bytesRead < this.rereadMessageHeaderBuffer.Length) { // Reset to the start of a new message. this.consumeStream.Seek(-bytesRead, SeekOrigin.Current); return(false); } MessageHeader.ReadHeaderFromBuffer(this.rereadMessageHeaderBuffer, 0, ref nextMessageHeader, headerSerializer); if (nextMessageHeader.Type == SerializedMessageType.CheckpointData) { // Skip this because we have already buffered these elements in memory. this.consumeStream.Seek(nextMessageHeader.Length, SeekOrigin.Current); Console.Error.WriteLine("Skipping a log message of length {0}", nextMessageHeader.Length); return(TryReadNextMessage()); } bytesRead = this.consumeStream.Read(this.rereadMessageBodyBuffer, 0, nextMessageHeader.Length); if (bytesRead < nextMessageHeader.Length) { // Reset to the start of a new message. this.consumeStream.Seek(-(bytesRead + MessageHeader.SizeOf), SeekOrigin.Current); return(false); } RecvBuffer messageBody = new RecvBuffer(this.rereadMessageBodyBuffer, 0, nextMessageHeader.Length); this.currentRereadMessage = new SerializedMessage(-1, nextMessageHeader, messageBody); this.currentRereadMessageEnumerator = this.decoder.Elements(currentRereadMessage).GetEnumerator(); this.currentRereadMessageEnumerator.MoveNext(); return(true); }
private void IngressThread() { MessageHeader parsedHeader = default(MessageHeader); T currentRecord = default(T); NaiadSerialization <T> serializer = AutoSerialization.GetSerializer <T>(); byte[] currentHeader = new byte[MessageHeader.SizeOf]; byte[] currentBody = new byte[PAGE_SIZE]; ConnectionState state = ConnectionState.Disconnected; foreach (Socket ingressSocket in this.socketQueue.GetConsumingEnumerable()) { try { state = ConnectionState.Connected; do { ReceiveAll(ingressSocket, currentHeader, currentHeader.Length); MessageHeader.ReadHeaderFromBuffer(currentHeader, 0, ref parsedHeader); Logging.Info("State = {0}; Event = {1}", state, (RemotingProtocol)parsedHeader.ChannelID); switch ((RemotingProtocol)parsedHeader.ChannelID) { case RemotingProtocol.OPEN_EPOCH_CHANNEL_ID: if (state == ConnectionState.Connected) { this.recipient.StartEpoch(); state = ConnectionState.Data; } else { goto default; } break; case RemotingProtocol.CLOSE_EPOCH_CHANNEL_ID: if (state == ConnectionState.Data) { this.recipient.EndEpoch(); state = ConnectionState.Connected; } else { goto default; } break; case RemotingProtocol.DATA_CHANNEL_ID: if (state == ConnectionState.Data) { ReceiveAll(ingressSocket, currentBody, parsedHeader.Length); RecvBuffer buffer = new RecvBuffer(currentBody, 0, parsedHeader.Length); while (serializer.TryDeserialize(ref buffer, out currentRecord)) { this.recipient.Send(currentRecord); } } else { goto default; } break; case RemotingProtocol.CLOSE_CONNECTION_CHANNEL_ID: if (state == ConnectionState.Connected) { ingressSocket.Close(); this.recipient.Close(); state = ConnectionState.Disconnected; } else { goto default; } break; case RemotingProtocol.SHUTDOWN_COMPUTATION_CHANNEL_ID: if (state == ConnectionState.Connected) { ingressSocket.Close(); this.recipient.Shutdown(); state = ConnectionState.Shutdown; } else { goto default; } return; default: // Error handling routine Logging.Info("Error reading from socket: {0}", ingressSocket); Debugger.Break(); if (this.recipient is Cancellable) { Logging.Info("Cancelling current epoch"); ((Cancellable)this.recipient).CancelEpoch(); } else { Logging.Info("Ending epoch prematurely: warning, data may be lost"); this.recipient.EndEpoch(); } state = ConnectionState.Disconnected; break; } } while (state != ConnectionState.Disconnected); continue; } catch (Exception) { Logging.Info("Error reading from socket: {0}", ingressSocket); if (this.recipient is Cancellable) { Logging.Info("Cancelling current epoch"); ((Cancellable)this.recipient).CancelEpoch(); } else { Logging.Info("Ending epoch prematurely: warning, data may be lost"); this.recipient.EndEpoch(); } state = ConnectionState.Disconnected; } } }
public override void Drain() { int recordsReceived = 0; byte[] consumeBuffer = null; for (; this.pagesRead < this.pagesFlushed; ++this.pagesRead) { Debug.Assert(this.consumeStream.Position % this.pageSize == 0); if (consumeBuffer == null) { consumeBuffer = ThreadLocalBufferPools <byte> .pool.Value.CheckOut(this.pageSize); } int bytesRead = this.consumeStream.Read(consumeBuffer, 0, this.pageSize); if (bytesRead < this.pageSize) { // We must be at the end of the file, where zero-bytes appear to be truncated. MessageHeader innerHeader = default(MessageHeader); MessageHeader.ReadHeaderFromBuffer(consumeBuffer, 0, ref innerHeader); if (innerHeader.Length + MessageHeader.SizeOf == bytesRead) { Logging.Info("Read complete data from partial page {0} bytes", bytesRead); // Get the consume stream in the correct place for the next read. this.consumeStream.Seek(this.pageSize - bytesRead, SeekOrigin.Current); } else { Debug.Assert(false); } } Debug.Assert(this.consumeStream.Position % this.pageSize == 0); if (this.serializer == null) { this.serializer = AutoSerialization.GetSerializer <Pair <S, T> >(); } MessageHeader header = default(MessageHeader); MessageHeader.ReadHeaderFromBuffer(consumeBuffer, 0, ref header); RecvBuffer messageBody = new RecvBuffer(consumeBuffer, MessageHeader.SizeOf, MessageHeader.SizeOf + header.Length); Pair <S, T> record; while (this.serializer.TryDeserialize(ref messageBody, out record)) { this.endpoint.RecordReceived(record, new RemotePostbox()); if (progressBuffer != null) { progressBuffer.Update(record.v2, -1); } ++recordsReceived; } Logging.Info("Drained a spilt page into operator {1}", recordsReceived, this.endpoint.Vertex); } if (recordsReceived > 0) { this.endpoint.Flush(); if (this.progressBuffer != null) { this.progressBuffer.Flush(); } this.postOffice.Controller.Workers.NotifyOperatorReceivedRecords(this.endpoint.Vertex, this.id, recordsReceived); Logging.Info("Drained {0} records into operator {1}", recordsReceived, this.endpoint.Vertex); } if (consumeBuffer != null) { ThreadLocalBufferPools <byte> .pool.Value.CheckIn(consumeBuffer); } }