internal void DispatchBasicReturn(ushort replyCode, string replyText, string exchange, string routingKey, int bodySize, BasicProperties properties, BaseLightStream ringBufferStream) { var ev = this.MessageUndeliveredHandler; var marker = new RingBufferPositionMarker(ringBufferStream); try { if (ev != null) { var inst = new UndeliveredMessage { bodySize = bodySize, stream = bodySize == 0 ? EmptyStream : ringBufferStream, properties = properties, routingKey = routingKey, replyCode = replyCode, replyText = replyText, exchange = exchange }; ev(inst); } } finally { marker.EnsureConsumed(bodySize); } }
public IList ReadArray() { // unbounded allocation again! bad! IList array = new List<object>(capacity: 10); var arrayLength = (int) _reader.ReadUInt32(); if (arrayLength == 0) return array; var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); while (marker.LengthRead < arrayLength) { object value = ReadFieldValue(); array.Add(value); } return array; }
public void ReadTable(IDictionary <string, object> table) { uint tableLength = _reader.ReadUInt32(); if (tableLength == 0) { return; } var marker = new RingBufferPositionMarker(_reader._ringBufferStream); while (marker.LengthRead < tableLength) { string key = ReadShortStr(internIt: false); object value = ReadFieldValue(); table[key] = value; } }
public IList ReadArray() { // unbounded allocation again! bad! IList array = new List <object>(capacity: 10); var arrayLength = (int)_reader.ReadUInt32(); if (arrayLength == 0) { return(array); } var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); while (marker.LengthRead < arrayLength) { object value = ReadFieldValue(); array.Add(value); } return(array); }
public IDictionary <string, object> ReadTable() { // unbounded allocation! bad var table = new Dictionary <string, object>(capacity: 11); uint tableLength = _reader.ReadUInt32(); if (tableLength == 0) { return(table); } var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); while (marker.LengthRead < tableLength) { string key = ReadShortStr(); object value = ReadFieldValue(); table[key] = value; } return(table); }
internal void DispatchDeliveredMessage( string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, int bodySize, BasicProperties properties, BaseLightStream lightStream) { BasicConsumerSubscriptionInfo consumer; if (!_consumerSubscriptions.TryGetValue(consumerTag, out consumer)) { // received msg but nobody was subscribed to get it (?) LogAdapter.LogWarn(LogSource, "Received message without a matching subscription. Discarding. " + "Exchange: " + exchange + " routing: " + routingKey + " consumer tag: " + consumerTag + " and channel " + this.ChannelNumber); // Ensure moved cursor ahead var marker = new RingBufferPositionMarker(lightStream); marker.EnsureConsumed(bodySize); return; } var delivery = new MessageDelivery { bodySize = bodySize, properties = properties, routingKey = routingKey, deliveryTag = deliveryTag + this._deliveryTagOffset, // adds tag offset redelivered = redelivered, }; var mode = consumer.Mode; var cb = consumer.Callback; var consumerInstance = consumer._consumer; if (mode == ConsumeMode.SingleThreaded) { // run with scissors, we're letting // the user code mess with the ring buffer in the name of performance delivery.stream = bodySize == 0 ? EmptyStream : lightStream; // upon return it's assumed the user has consumed from the stream and is done with it var marker = new RingBufferPositionMarker(lightStream); try { if (cb != null) { cb(delivery).GetAwaiter().GetResult(); } else { consumerInstance.Consume(delivery).GetAwaiter().GetResult(); } } finally { if (!delivery.TakenOver) { delivery.Dispose(); } // fingers crossed the user cloned the buffer if she needs it later marker.EnsureConsumed(bodySize); } } else { // parallel mode. it cannot hold the frame handler, so we copy the buffer (yuck) and move forward if (mode == ConsumeMode.ParallelWithBufferCopy || mode == ConsumeMode.SerializedWithBufferCopy) { delivery.stream = delivery.bodySize == 0 ? EmptyStream : lightStream.CloneStream(bodySize); } if (mode == ConsumeMode.SerializedWithBufferCopy) // Posts to a thread { if (consumer._consumerThread == null) { // Initialization. safe since this delivery call always happen from the same thread consumer._receivedMessages = new ConcurrentQueue <MessageDelivery>(); consumer._messageAvailableEv = new AutoResetEvent(false); consumer._consumerThread = ThreadFactory.BackgroundThread(SerializedDelivery, "Delivery_" + consumer.ConsumerTag, consumer); } consumer._receivedMessages.Enqueue(delivery); consumer._messageAvailableEv.Set(); } else if (mode == ConsumeMode.ParallelWithBufferCopy) // Posts to TaskScheduler { new Task(async state => { var tuple = (Tuple <MessageDelivery, Func <MessageDelivery, Task>, IQueueConsumer, Channel>)state; var delivery1 = tuple.Item1; var cb1 = tuple.Item2; var conInstance = tuple.Item3; try { if (cb1 != null) { await cb1(delivery1).ConfigureAwait(false); } else { await conInstance.Consume(delivery1).ConfigureAwait(false); } } catch (Exception e) { if (LogAdapter.IsErrorEnabled) { LogAdapter.LogError(LogSource, "Error processing message (user code)", e); } } finally { if (!delivery1.TakenOver) { delivery1.Dispose(); } } }, Tuple.Create(delivery, cb, consumerInstance, this)) // tuple avoids the closure capture // Start task in the given scheduler .Start(_schedulerToDeliverMessages); } } }
public async Task Read_BasicDelivery(Func<string, ulong, bool, string, string, int, BasicProperties, Stream, Task> continuation, BasicProperties properties) { string consumerTag = _amqpReader.ReadShortStr(); ulong deliveryTag = _amqpReader.ReadULong(); bool redelivered = _amqpReader.ReadBits() != 0; string exchange = _amqpReader.ReadShortStr(); string routingKey = _amqpReader.ReadShortStr(); byte frameEndMarker = _amqpReader.ReadOctet(); if (frameEndMarker != AmqpConstants.FrameEnd) throw new Exception("Expecting frameend!"); // Frame Header / Content header byte frameHeaderStart = _amqpReader.ReadOctet(); if (frameHeaderStart != AmqpConstants.FrameHeader) throw new Exception("Expecting Frame Header"); // await _reader.SkipBy(4 + 2 + 2 + 2); ushort channel = _reader.ReadUInt16(); int payloadLength = _reader.ReadInt32(); ushort classId = _reader.ReadUInt16(); ushort weight = _reader.ReadUInt16(); long bodySize = (long) _reader.ReadUInt64(); // BasicProperties properties = ReadRestOfContentHeader(); ReadRestOfContentHeader(properties, bodySize == 0); // Frame Body(s) if (bodySize != 0) { // Support just single body at this moment. frameHeaderStart = _reader.ReadByte(); if (frameHeaderStart != AmqpConstants.FrameBody) throw new Exception("Expecting Frame Body"); // await _reader.SkipBy(2); channel = _reader.ReadUInt16(); uint length = _reader.ReadUInt32(); // Pending Frame end if (length == bodySize) { var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); await continuation(consumerTag, deliveryTag, redelivered, exchange, routingKey, (int) length, properties, (Stream) _reader._ringBufferStream); if (marker.LengthRead < length) { checked { int offset = (int) (length - marker.LengthRead); await _reader.SkipBy(offset); } } } else { throw new NotSupportedException("Multi body not supported yet. Total body size is " + bodySize + " and first body is " + length + " bytes"); } } else { // Empty body size, which is OK await continuation(consumerTag, deliveryTag, redelivered, exchange, routingKey, 0, properties, EmptyStream); } }
public async Task Read_BasicReturn(Func<ushort, string, string, string, int, BasicProperties, Stream, Task> continuation, BasicProperties properties) { ushort replyCode = _amqpReader.ReadShort(); string replyText = _amqpReader.ReadShortStr(); string exchange = _amqpReader.ReadShortStr(); string routingKey = _amqpReader.ReadShortStr(); byte frameEndMarker = _amqpReader.ReadOctet(); if (frameEndMarker != AmqpConstants.FrameEnd) throw new Exception("Expecting frameend!"); // Frame Header / Content header byte frameHeaderStart = _amqpReader.ReadOctet(); if (frameHeaderStart != AmqpConstants.FrameHeader) throw new Exception("Expecting Frame Header"); // await _reader.SkipBy(4 + 2 + 2 + 2); ushort channel = _reader.ReadUInt16(); int payloadLength = _reader.ReadInt32(); ushort classId = _reader.ReadUInt16(); ushort weight = _reader.ReadUInt16(); var bodySize = (long) _reader.ReadUInt64(); // BasicProperties properties = ReadRestOfContentHeader(); ReadRestOfContentHeader(properties, bodySize == 0); // Frame Body(s) if (bodySize != 0) { frameHeaderStart = _reader.ReadByte(); if (frameHeaderStart != AmqpConstants.FrameBody) throw new Exception("Expecting Frame Body"); await _reader.SkipBy(2); // channel = _reader.ReadUInt16(); uint length = _reader.ReadUInt32(); // must leave pending Frame end if (length == bodySize) { // continuation(replyCode, replyText, exchange, routingKey); var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); await continuation(replyCode, replyText, exchange, routingKey, (int)length, properties, _reader._ringBufferStream); if (marker.LengthRead < length) { checked { int offset = (int)(length - marker.LengthRead); await _reader.SkipBy(offset); } } } else { throw new NotSupportedException("Multi body not supported yet. Total body size is " + bodySize + " and first body is " + length + " bytes"); } } else { // no body await continuation(replyCode, replyText, exchange, routingKey, 0, properties, EmptyStream); } }
public async Task Read_BasicDelivery(Func <string, ulong, bool, string, string, int, BasicProperties, Stream, Task> continuation, BasicProperties properties) { string consumerTag = _amqpReader.ReadShortStr(); ulong deliveryTag = _amqpReader.ReadULong(); bool redelivered = _amqpReader.ReadBits() != 0; string exchange = _amqpReader.ReadShortStr(); string routingKey = _amqpReader.ReadShortStr(); byte frameEndMarker = _amqpReader.ReadOctet(); if (frameEndMarker != AmqpConstants.FrameEnd) { throw new Exception("Expecting frameend!"); } // Frame Header / Content header byte frameHeaderStart = _amqpReader.ReadOctet(); if (frameHeaderStart != AmqpConstants.FrameHeader) { throw new Exception("Expecting Frame Header"); } // await _reader.SkipBy(4 + 2 + 2 + 2); ushort channel = _reader.ReadUInt16(); int payloadLength = _reader.ReadInt32(); ushort classId = _reader.ReadUInt16(); ushort weight = _reader.ReadUInt16(); long bodySize = (long)_reader.ReadUInt64(); // BasicProperties properties = ReadRestOfContentHeader(); ReadRestOfContentHeader(properties, bodySize == 0); // Frame Body(s) if (bodySize != 0) { // Support just single body at this moment. frameHeaderStart = _reader.ReadByte(); if (frameHeaderStart != AmqpConstants.FrameBody) { throw new Exception("Expecting Frame Body"); } // await _reader.SkipBy(2); channel = _reader.ReadUInt16(); uint length = _reader.ReadUInt32(); // Pending Frame end if (length == bodySize) { var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); await continuation(consumerTag, deliveryTag, redelivered, exchange, routingKey, (int)length, properties, (Stream)_reader._ringBufferStream); if (marker.LengthRead < length) { checked { int offset = (int)(length - marker.LengthRead); await _reader.SkipBy(offset); } } } else { throw new NotSupportedException("Multi body not supported yet. Total body size is " + bodySize + " and first body is " + length + " bytes"); } } else { // Empty body size, which is OK await continuation(consumerTag, deliveryTag, redelivered, exchange, routingKey, 0, properties, EmptyStream); } }
public async Task Read_BasicReturn(Func <ushort, string, string, string, int, BasicProperties, Stream, Task> continuation, BasicProperties properties) { ushort replyCode = _amqpReader.ReadShort(); string replyText = _amqpReader.ReadShortStr(); string exchange = _amqpReader.ReadShortStr(); string routingKey = _amqpReader.ReadShortStr(); byte frameEndMarker = _amqpReader.ReadOctet(); if (frameEndMarker != AmqpConstants.FrameEnd) { throw new Exception("Expecting frameend!"); } // Frame Header / Content header byte frameHeaderStart = _amqpReader.ReadOctet(); if (frameHeaderStart != AmqpConstants.FrameHeader) { throw new Exception("Expecting Frame Header"); } // await _reader.SkipBy(4 + 2 + 2 + 2); ushort channel = _reader.ReadUInt16(); int payloadLength = _reader.ReadInt32(); ushort classId = _reader.ReadUInt16(); ushort weight = _reader.ReadUInt16(); var bodySize = (long)_reader.ReadUInt64(); // BasicProperties properties = ReadRestOfContentHeader(); ReadRestOfContentHeader(properties, bodySize == 0); // Frame Body(s) if (bodySize != 0) { frameHeaderStart = _reader.ReadByte(); if (frameHeaderStart != AmqpConstants.FrameBody) { throw new Exception("Expecting Frame Body"); } await _reader.SkipBy(2); // channel = _reader.ReadUInt16(); uint length = _reader.ReadUInt32(); // must leave pending Frame end if (length == bodySize) { // continuation(replyCode, replyText, exchange, routingKey); var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); await continuation(replyCode, replyText, exchange, routingKey, (int)length, properties, _reader._ringBufferStream); if (marker.LengthRead < length) { checked { int offset = (int)(length - marker.LengthRead); await _reader.SkipBy(offset); } } } else { throw new NotSupportedException("Multi body not supported yet. Total body size is " + bodySize + " and first body is " + length + " bytes"); } } else { // no body await continuation(replyCode, replyText, exchange, routingKey, 0, properties, EmptyStream); } }
public IDictionary<string, object> ReadTable() { // unbounded allocation! bad var table = new Dictionary<string, object>(capacity: 11); uint tableLength = _reader.ReadUInt32(); if (tableLength == 0) return table; var marker = new RingBufferPositionMarker(_reader._ringBufferStream._ringBuffer); while (marker.LengthRead < tableLength) { string key = ReadShortStr(); object value = ReadFieldValue(); table[key] = value; } return table; }