public bool TakeMessage(CancellationToken token, out EnvelopeTransportContext context)
        {
            ImmutableEnvelope envelope;

            while (!token.IsCancellationRequested)
            {
                // if incoming message is delayed and in future -> push it to the timer queue.
                // timer will be responsible for publishing back.

                var result = BlockingCollection <ImmutableEnvelope> .TakeFromAny(_queues, out envelope);

                if (result >= 0)
                {
                    if (envelope.DeliverOnUtc > DateTime.UtcNow)
                    {
                        // future message
                        throw new InvalidOperationException("Message scheduling has been disabled in the code");
                    }
                    context = new EnvelopeTransportContext(result, envelope, _names[result]);
                    return(true);
                }
            }
            context = null;
            return(false);
        }
Esempio n. 2
0
 /// <summary>
 /// ACKs the message by deleting it from the queue.
 /// </summary>
 /// <param name="envelope">The message context to ACK.</param>
 public void AckMessage(EnvelopeTransportContext envelope)
 {
     if (envelope == null)
     {
         throw new ArgumentNullException("message");
     }
     ((FileInfo)envelope.TransportMessage).Delete();
 }
Esempio n. 3
0
 /// <summary>
 /// ACKs the message by deleting it from the queue.
 /// </summary>
 /// <param name="envelope">The message context to ACK.</param>
 public void AckMessage(EnvelopeTransportContext envelope)
 {
     if (envelope == null)
     {
         throw new ArgumentNullException("message");
     }
     _queue.DeleteMessage((CloudQueueMessage)envelope.TransportMessage);
 }
 public void AckMessage(EnvelopeTransportContext envelope)
 {
     foreach (var queue in _readers)
     {
         if (queue.Name == envelope.QueueName)
         {
             queue.AckMessage(envelope);
         }
     }
 }
        void ProcessMessage(EnvelopeTransportContext context)
        {
            var processed = false;

            try
            {
                if (_memory.DoWeRemember(context.Unpacked.EnvelopeId))
                {
                    _observer.Notify(new EnvelopeDuplicateDiscarded(context.QueueName, context.Unpacked.EnvelopeId));
                }
                else
                {
                    _dispatcher.DispatchMessage(context.Unpacked);
                    _memory.Memorize(context.Unpacked.EnvelopeId);
                }

                processed = true;
            }
            catch (Exception dispatchEx)
            {
                // if the code below fails, it will just cause everything to be reprocessed later,
                // which is OK (duplication manager will handle this)

                _observer.Notify(new EnvelopeDispatchFailed(context.Unpacked, context.QueueName, dispatchEx));
                // quarantine is atomic with the processing
                if (_quarantine.TryToQuarantine(context, dispatchEx))
                {
                    _observer.Notify(new EnvelopeQuarantined(dispatchEx, context.Unpacked, context.QueueName));
                    // acking message is the last step!
                    _inbox.AckMessage(context);
                }
                else
                {
                    _inbox.TryNotifyNack(context);
                }
            }
            try
            {
                if (processed)
                {
                    // 1st step - dequarantine, if present
                    _quarantine.TryRelease(context);
                    // 2nd step - ack.
                    _inbox.AckMessage(context);
                    // 3rd - notify.
                    _observer.Notify(new EnvelopeAcked(context.QueueName, context.Unpacked.EnvelopeId, context.Unpacked.GetAllAttributes()));
                }
            }
            catch (Exception ex)
            {
                // not a big deal. Message will be processed again.
                _observer.Notify(new EnvelopeAckFailed(ex, context.Unpacked.EnvelopeId, context.QueueName));
            }
        }
Esempio n. 6
0
        public bool TryToQuarantine(EnvelopeTransportContext context, Exception ex)
        {
            var current = _failures.AddOrUpdate(context.Unpacked.EnvelopeId, s => 1, (s1, i) => i + 1);

            if (current < 4)
            {
                return(false);
            }
            // accept and forget
            int forget;

            _failures.TryRemove(context.Unpacked.EnvelopeId, out forget);
            return(true);
        }
        public bool TakeMessage(CancellationToken token, out EnvelopeTransportContext context)
        {
            while (!token.IsCancellationRequested)
            {
                for (var i = 0; i < _readers.Length; i++)
                {
                    var queue = _readers[i];

                    var message = queue.TryGetMessage();
                    switch (message.State)
                    {
                    case GetEnvelopeResultState.Success:

                        _emptyCycles = 0;
                        // future message
                        if (message.Envelope.Unpacked.DeliverOnUtc > DateTime.UtcNow)
                        {
                            throw new InvalidOperationException("Future message delivery has been disabled in the code");
                        }
                        context = message.Envelope;
                        return(true);

                    case GetEnvelopeResultState.Empty:
                        _emptyCycles += 1;
                        break;

                    case GetEnvelopeResultState.Exception:
                        // access problem, fall back a bit
                        break;

                    case GetEnvelopeResultState.Retry:
                        // this could be the poison
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                    var waiting = _waiter(_emptyCycles);
                    token.WaitHandle.WaitOne(waiting);
                }
            }
            context = null;
            return(false);
        }
Esempio n. 8
0
        public void TryRelease(EnvelopeTransportContext context)
        {
            int value;

            _failures.TryRemove(context.Unpacked.EnvelopeId, out value);
        }
 public void TryNotifyNack(EnvelopeTransportContext context)
 {
 }
        public void TryNotifyNack(EnvelopeTransportContext context)
        {
            var id = (int)context.TransportMessage;

            _queues[id].Add(context.Unpacked);
        }
 public void AckMessage(EnvelopeTransportContext envelope)
 {
 }