Exemplo n.º 1
0
        /// <summary>
        /// Renews a lock on a message that makes it invisible from other receivers in
        /// the queue.This method is usually used to extend the message processing time.
        /// </summary>
        /// <param name="message">a message to extend its lock.</param>
        /// <param name="lockTimeout">a locking timeout in milliseconds.</param>
        public override async Task RenewLockAsync(MessageEnvelope message, long lockTimeout)
        {
            if (message.Reference == null)
            {
                return;
            }

            lock (_lock)
            {
                // Get message from locked queue
                LockedMessage lockedMessage = null;
                int           lockedToken   = (int)message.Reference;

                // If lock is found, extend the lock
                if (_lockedMessages.TryGetValue(lockedToken, out lockedMessage))
                {
                    // Todo: Shall we skip if the message already expired?
                    if (lockedMessage.ExpirationTimeUtc > DateTime.UtcNow)
                    {
                        lockedMessage.ExpirationTimeUtc = DateTime.UtcNow.Add(lockedMessage.Timeout);
                    }
                }
            }

            _logger.Trace(message.CorrelationId, "Renewed lock for message {0} at {1}", message, this);

            await Task.Delay(0);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Receives an incoming message and removes it from the queue.
        /// </summary>
        /// <param name="correlationId">(optional) transaction id to trace execution through call chain.</param>
        /// <param name="waitTimeout">a timeout in milliseconds to wait for a message to come.</param>
        /// <returns>a message envelop object.</returns>
        public override async Task <MessageEnvelope> ReceiveAsync(string correlationId, long waitTimeout)
        {
            await Task.Delay(0);

            lock (_lock)
            {
                if (_messages.Count == 0)
                {
                    _receiveEvent.Reset();
                }
                else
                {
                    _receiveEvent.Set();
                }
            }

            _receiveEvent.WaitOne(TimeSpan.FromMilliseconds(waitTimeout));

            MessageEnvelope message = null;

            lock (_lock)
            {
                if (_messages.Count == 0)
                {
                    return(null);
                }

                // Get message the the queue
                message = _messages.Dequeue();

                if (message != null)
                {
                    // Generate and set locked token
                    var lockedToken = _lockTokenSequence++;
                    message.Reference = lockedToken;

                    // Add messages to locked messages list
                    var lockedMessage = new LockedMessage
                    {
                        ExpirationTimeUtc = DateTime.UtcNow.AddMilliseconds(waitTimeout),
                        Message           = message,
                        Timeout           = TimeSpan.FromMilliseconds(waitTimeout)
                    };
                    _lockedMessages.Add(lockedToken, lockedMessage);
                }
            }

            if (message != null)
            {
                _counters.IncrementOne("queue." + Name + ".received_messages");
                _logger.Debug(message.CorrelationId, "Received message {0} via {1}", message, this);
            }

            return(message);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns message into the queue and makes it available for all subscribers to
        /// receive it again.This method is usually used to return a message which could
        /// not be processed at the moment to repeat the attempt.Messages that cause
        /// unrecoverable errors shall be removed permanently or/and send to dead letter queue.
        /// </summary>
        /// <param name="message">a message to return.</param>
        public override async Task AbandonAsync(MessageEnvelope message)
        {
            if (message.Reference == null)
            {
                return;
            }

            lock (_lock)
            {
                // Get message from locked queue
                int           lockedToken   = (int)message.Reference;
                LockedMessage lockedMessage = null;
                if (_lockedMessages.TryGetValue(lockedToken, out lockedMessage))
                {
                    // Remove from locked messages
                    _lockedMessages.Remove(lockedToken);
                    message.Reference = null;

                    // Skip if it is already expired
                    if (lockedMessage.ExpirationTimeUtc <= DateTime.UtcNow)
                    {
                        return;
                    }
                }
                // Skip if it absent
                else
                {
                    return;
                }
            }

            _logger.Trace(message.CorrelationId, "Abandoned message {0} at {1}", message, this);

            // Add back to the queue
            await SendAsync(message.CorrelationId, message);
        }