private async Task <RedisMessage <T> > GetMessageAsync()
        {
            try
            {
                var listItem = await _db.ListRightPopLeftPushAsync(_queueName, RedisQueueConventions.GetProcessingQueueName(_queueName)).ConfigureAwait(false);

                if (listItem.IsNullOrEmpty)
                {
                    return(null);
                }
                var message = _redisConfiguration.MessageSerializer.Deserialize <T>(listItem);
                var hashKey = RedisQueueConventions.GetMessageHashKey(_queueName, message.Id);

                var tasks = new Task[]
                {
                    _db.StringSetAsync(RedisQueueConventions.GetMessageExpirationKey(_queueName, message.Id), DateTimeOffset.Now.ToUnixTimeMilliseconds()),
                    _db.HashIncrementAsync(hashKey, RedisHashKeys.DeliveryCount, 1),
                };
                await Task.WhenAll(tasks).ConfigureAwait(false);

                var hash = await _db.HashGetAllAsync(hashKey).ConfigureAwait(false);

                return(new RedisMessage <T>(listItem, message, hash, _queueName));
            }
            catch (RedisTimeoutException e)
            {
                _hostConfiguration.Log.Error(e, "Error retrieving redis message");
                return(null);
            }
            catch (RedisException e)
            {
                _hostConfiguration.Log.Error(e, "Error retrieving redis message");
                return(null);
            }
        }
Esempio n. 2
0
 public RedisMessage(RedisValue redisValue, string id, T message, HashEntry[] hashEntries, string queueName)
 {
     RedisValue    = redisValue;
     HashKey       = RedisQueueConventions.GetMessageHashKey(queueName, id);
     ExpirationKey = RedisQueueConventions.GetMessageExpirationKey(queueName, id);
     Message       = message;
     HashEntries   = hashEntries.ToStringDictionary();
 }
Esempio n. 3
0
        internal Task DeleteDeadletterAsync(RedisDeadletter <T> deadletter)
        {
            var deadletterQueueName = RedisQueueConventions.GetDeadLetterQueueName(_queueName);
            var hash          = RedisQueueConventions.GetMessageHashKey(_queueName, deadletter.Message.Id);
            var expirationKey = RedisQueueConventions.GetMessageExpirationKey(_queueName, deadletter.Message.Id);

            return(Task.WhenAll(_db.KeyDeleteAsync(new RedisKey[] { hash, expirationKey }),
                                _db.ListRemoveAsync(deadletterQueueName, _serializer.Serialize(deadletter.Message), -1)));
        }
Esempio n. 4
0
        private async Task <RedisMessage <T> > GetMessageAsync(CancellationTokenSource cancellationsSource)
        {
            if (cancellationsSource.IsCancellationRequested)
            {
                return(null);
            }

            try
            {
                byte[] listItem = await _db.ListRightPopLeftPushAsync(_queueName, RedisQueueConventions.GetProcessingQueueName(_queueName)).ConfigureAwait(false);

                if (listItem == null)
                {
                    cancellationsSource.Cancel();
                    return(null);
                }

                var message = _serializer.Deserialize <RedisListItem <T> >(listItem.AsSpan());
                var hashKey = RedisQueueConventions.GetMessageHashKey(_queueName, message.Id);

                var tasks = new Task[]
                {
                    _db.StringSetAsync(RedisQueueConventions.GetMessageExpirationKey(_queueName, message.Id), DateTimeOffset.Now.ToUnixTimeMilliseconds()),
                    _db.HashIncrementAsync(hashKey, RedisHashKeys.DeliveryCount)
                };
                await Task.WhenAll(tasks).ConfigureAwait(false);

                var hash = await _db.HashGetAllAsync(hashKey).ConfigureAwait(false);

                return(new RedisMessage <T>(listItem, message.Id, message.Body, hash, _queueName));
            }
            catch (RedisTimeoutException e)
            {
                _log.Error(e, "Error retrieving redis message");
                return(null);
            }
            catch (RedisException e)
            {
                _log.Error(e, "Error retrieving redis message");
                return(null);
            }
        }
Esempio n. 5
0
        private async Task <(bool lost, RedisListItem <T> message, RedisValue listItem)> HandlePotentiallyLostMessage(string queueName, byte[] listItem)
        {
            var message          = _serializer.Deserialize <RedisListItem <T> >(listItem.AsSpan());
            var lastProcessedKey = RedisQueueConventions.GetMessageExpirationKey(queueName, message.Id);
            var hash             = await _db.StringGetAsync(lastProcessedKey).ConfigureAwait(false);

            if (!hash.IsNull)
            {
                var processTimeStamp = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(hash));
                if (processTimeStamp + _messageTimeout < DateTimeOffset.Now)
                {
                    //Message is lost or has exceeded maximum processing time
                    return(true, message, listItem);
                }
            }
            else
            {
                await _db.StringSetAsync(lastProcessedKey, DateTimeOffset.Now.Add(-_messageTimeout).ToUnixTimeMilliseconds(), GetDelay() + GetDelay()).ConfigureAwait(false);
            }

            return(false, default, listItem);
Esempio n. 6
0
        internal async Task RequeueDeadletterAsync()
        {
            var deadLetterQueueName           = RedisQueueConventions.GetDeadLetterQueueName(_queueName);
            var deadLetterProcessingQueueName = RedisQueueConventions.GetProcessingQueueName(deadLetterQueueName);

            byte[] listItem = await _db.ListRightPopLeftPushAsync(deadLetterQueueName, deadLetterProcessingQueueName).ConfigureAwait(false);

            if (listItem == null)
            {
                return;
            }
            var message       = _serializer.Deserialize <RedisListItem <T> >(listItem.AsSpan());
            var hashKey       = RedisQueueConventions.GetMessageHashKey(_queueName, message.Id);
            var expirationKey = RedisQueueConventions.GetMessageExpirationKey(_queueName, message.Id);

            await _db.HashDeleteAsync(hashKey, new RedisValue[] { expirationKey, RedisHashKeys.DeliveryCount }).ConfigureAwait(false);

            await _db.ListRightPopLeftPushAsync(deadLetterProcessingQueueName, _queueName).ConfigureAwait(false);

            await _db.PublishAsync(_queueName, 0, CommandFlags.FireAndForget).ConfigureAwait(false);
        }