Example #1
0
        public void Create_Default_Serialized()
        {
            var id    = Guid.NewGuid();
            var input = new RedisQueueCorrelationIdSerialized(id);
            var test  = new RedisQueueCorrelationId(input);

            Assert.Equal(id.ToString(), test.Id.Value.ToString());
            Assert.True(test.HasValue);
        }
        /// <inheritdoc />
        public RedisMessage Handle(ReceiveMessageQuery query)
        {
            byte[] message = null;
            byte[] headers = null;
            string messageId;
            var    poisonMessage = false;
            RedisQueueCorrelationIdSerialized correlationId = null;

            try
            {
                var          unixTimestamp = _unixTimeFactory.Create().GetCurrentUnixTimestampMilliseconds();
                RedisValue[] result;
                if (query.MessageId != null && query.MessageId.HasValue)
                {
                    result = _dequeueRpcLua.Execute(query.MessageId.Id.Value.ToString(), unixTimestamp);
                }
                else
                {
                    result = _dequeueLua.Execute(unixTimestamp);
                }

                if (result == null || result.Length == 1 && !result[0].HasValue || !result[0].HasValue)
                {
                    return(null);
                }

                if (!result[1].HasValue)
                {
                    //at this point, the record has been de-queued, but it can't be processed.
                    poisonMessage = true;
                }

                messageId = result[0];
                var id = new RedisQueueId(messageId);
                query.MessageContext.MessageId = id;
                if (!poisonMessage)
                {
                    message = result[1];
                    headers = result[2];
                    if (result[3].HasValue)
                    {
                        if (result[3].TryParse(out long messageExpiration))
                        {
                            if (messageExpiration - unixTimestamp < 0)
                            {
                                //message has expired
                                _deleteMessage.Handle(new DeleteMessageCommand(new RedisQueueId(messageId)));
                                return(new RedisMessage(messageId, null, true));
                            }
                        }
                    }
                }
            }
            catch (Exception error)
            {
                throw new ReceiveMessageException("Failed to dequeue a message", error);
            }

            if (poisonMessage)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message de-queued from Redis; a messageId was returned, but the LUA script returned a null message. The message payload has most likely been lost.", null,
                          new RedisQueueId(messageId), new RedisQueueCorrelationId(Guid.Empty),
                          null, null);
            }

            try
            {
                var allHeaders = _serializer.InternalSerializer.ConvertBytesTo <IDictionary <string, object> > (headers);
                correlationId = (RedisQueueCorrelationIdSerialized)allHeaders[_redisHeaders.CorrelationId.Name];
                var messageGraph = (MessageInterceptorsGraph)allHeaders[_redisHeaders.Headers.StandardHeaders.MessageInterceptorGraph.Name];
                var messageData  = _serializer.Serializer.BytesToMessage <MessageBody>(message, messageGraph);

                var newMessage = _messageFactory.Create(messageData.Body, allHeaders);

                return(new RedisMessage(
                           messageId,
                           _receivedMessageFactory.Create(
                               newMessage,
                               new RedisQueueId(messageId),
                               new RedisQueueCorrelationId(correlationId.Id)), false));
            }
            catch (Exception error)
            {
                //at this point, the record has been de-queued, but it can't be processed.
                throw new PoisonMessageException(
                          "An error has occurred trying to re-assemble a message de-queued from redis", error,
                          new RedisQueueId(messageId), new RedisQueueCorrelationId(correlationId),
                          message, headers);
            }
        }