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); }
/// <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(); }
/// <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)); } }
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); }
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) { }