Пример #1
0
        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);
        }
Пример #6
0
        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);
			}
		}
Пример #9
0
        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);
            }
        }
Пример #10
0
        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;
        }