コード例 #1
0
        static void RenderAdditionalContent(StringBuilder builder, EnvelopeTransportContext context)
        {
            var s = Environment.NewLine;

            builder.AppendLine("Created:  " + context.Unpacked.CreatedOnUtc + "UTC");
            builder.AppendLine("Envelope: " + context.Unpacked.EnvelopeId);
            builder.AppendLine("Queue:    " + context.QueueName);

            foreach (var attribute in context.Unpacked.GetAllAttributes())
            {
                builder.AppendLine(attribute.Key + ": " + attribute.Value);
            }

            foreach (var message in context.Unpacked.Items)
            {
                builder.AppendFormat("{0}. {1}{2}", message.Index, message.MappedType, s);

                foreach (var attribute in message.GetAllAttributes())
                {
                    builder.AppendFormat("  {0}: {1}{2}", attribute.Key, attribute.Value, s);
                }
                builder.AppendLine(JsonConvert.SerializeObject(message.Content, Formatting.Indented));
                builder.AppendLine();
            }
        }
コード例 #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");

            DeleteMessage((QueueMessage)envelope.TransportMessage);
        }
コード例 #3
0
 public void AckMessage(EnvelopeTransportContext envelope)
 {
     foreach (var queue in _readers)
     {
         if (queue.Name == envelope.QueueName)
         {
             queue.AckMessage(envelope);
         }
     }
 }
コード例 #4
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;
 }
コード例 #5
0
        public bool TryToQuarantine(EnvelopeTransportContext context, Exception ex)
        {
            bool quarantined = _quarantine.TryToQuarantine(context, ex);

            var builder = new StringBuilder();

            RenderAdditionalContent(builder, context);

            builder.AppendLine("[Exception]");
            builder.AppendLine(DateTime.UtcNow.ToString());
            builder.AppendLine(ex.ToString());
            builder.AppendLine();

            Trace.WriteLine(builder.ToString());

            return quarantined;
        }
コード例 #6
0
        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;
        }
コード例 #7
0
        public bool TryToQuarantine(EnvelopeTransportContext context, Exception ex)
        {
            var quarantined = _quarantine.TryToQuarantine(context, ex);

            try
            {
                var item = GetStreamingItem(context);
                var data = "";
                try
                {
                    data = item.ReadText();
                }
                catch (StreamingItemNotFoundException)
                {
                }

                var builder = new StringBuilder(data);
                if (builder.Length == 0)
                {
                    DescribeMessage(builder, context);
                }

                builder.AppendLine("[Exception]");
                builder.AppendLine(DateTime.UtcNow.ToString());
                builder.AppendLine(ex.ToString());
                builder.AppendLine();

                var text = builder.ToString();
                item.WriteText(text);
            }
            catch (Exception x)
            {
                Trace.WriteLine(x.ToString());
            }

            return quarantined;
        }
コード例 #8
0
        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;
        }
コード例 #9
0
 public void TryRelease(EnvelopeTransportContext context)
 {
     _quarantine.TryRelease(context);
 }
コード例 #10
0
 public static GetEnvelopeResult Success(EnvelopeTransportContext envelope)
 {
     return new GetEnvelopeResult(envelope, GetEnvelopeResultState.Success);
 }
コード例 #11
0
 GetEnvelopeResult(EnvelopeTransportContext envelope, GetEnvelopeResultState state)
 {
     _envelope = envelope;
     State = state;
 }
コード例 #12
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();
 }
コード例 #13
0
 public static GetEnvelopeResult Success(EnvelopeTransportContext envelope)
 {
     return(new GetEnvelopeResult(envelope, GetEnvelopeResultState.Success));
 }
コード例 #14
0
 static void DescribeMessage(StringBuilder builder, EnvelopeTransportContext context)
 {
     builder.AppendLine(string.Format("{0,12}: {1}", "Queue", context.QueueName));
     builder.AppendLine(context.Unpacked.PrintToString(o => JsonConvert.SerializeObject(o, Formatting.Indented)));
 }
コード例 #15
0
 public void AckMessage(EnvelopeTransportContext envelope)
 {
 }
コード例 #16
0
        public GetEnvelopeResult TryGetMessage()
        {
            QueueMessage message;

            try
            {
                using (var db = new DataContext(_config.ConnectionString))
                {
                    message = db
                        .ExecuteQuery<QueueMessage>
                        (
                            "exec [dbo].[Dequeue] {0}, {1}, {2}",
                            _queueID,
                            _visibilityTimeout.TotalSeconds,
                            1
                        )
                        .FirstOrDefault();
                }
            }
            catch(Exception ex)
            {
                _observer.Notify(new FailedToReadMessage(ex, _queueName));
                return GetEnvelopeResult.Error();
            }

            if (message == null)
                return GetEnvelopeResult.Empty;

            try
            {
                var envelope = _streamer.ReadAsEnvelopeData(message.Envelope.ToArray());
                var context = new EnvelopeTransportContext(message, envelope, _queueName);
                return GetEnvelopeResult.Success(context);
            }
            catch(Exception ex)
            {
                _observer.Notify(new EnvelopeDeserializationFailed(ex, _queueName, message.EnvelopeID));
                SendToPoisonQueue(message);
                DeleteMessage(message);
                return GetEnvelopeResult.Retry;
            }
        }
コード例 #17
0
        IStreamingItem GetStreamingItem(EnvelopeTransportContext context)
        {
            var createdOnUtc = context.Unpacked.CreatedOnUtc;

            var file = string.Format("{0:yyyy-MM-dd-HH-mm}-{1}-engine.txt",
                createdOnUtc,
                context.Unpacked.EnvelopeId.ToLowerInvariant());

            return _container.GetItem(file);
        }
コード例 #18
0
        public void TryNotifyNack(EnvelopeTransportContext context)
        {
            var id = (int) context.TransportMessage;

            _queues[id].Add(context.Unpacked);
        }
コード例 #19
0
 GetEnvelopeResult(EnvelopeTransportContext envelope, GetEnvelopeResultState state)
 {
     _envelope = envelope;
     State     = state;
 }
コード例 #20
0
 public void TryNotifyNack(EnvelopeTransportContext context)
 {
 }
コード例 #21
0
 public void TryRelease(EnvelopeTransportContext context)
 {
     int value;
     _failures.TryRemove(context.Unpacked.EnvelopeId, out value);
 }