예제 #1
0
        private async Task HandleUndeliverable(T message)
        {
            if (_undeliverableConsumer != null)
            {
                var attempts = TryGetAttempts(message);

                if (_errorConsumer != null)
                {
                    try
                    {
                        await _undeliverableConsumer.HandleAsync(new QueuedMessage <T>
                        {
                            Attempts = attempts, Message = message
                        });
                    }
                    catch (Exception e)
                    {
                        await _errorConsumer.HandleAsync(e);
                    }
                }
                else
                {
                    await _undeliverableConsumer.HandleAsync(new QueuedMessage <T>
                    {
                        Attempts = attempts, Message = message
                    });
                }

                Interlocked.Increment(ref _undelivered);
                if (RetryPolicy != null)
                {
                    _attempts.Remove(HashMessage(message));
                }
            }
        }
예제 #2
0
 private async Task HandleBacklog(T message, int attempts)
 {
     if (_backlogConsumer != null)
     {
         if (_errorConsumer != null)
         {
             try
             {
                 if (!await _backlogConsumer.HandleAsync(new QueuedMessage <T>
                 {
                     Attempts = attempts, Message = message
                 }))
                 {
                     await HandleUndeliverable(message);
                 }
             }
             catch (Exception e)
             {
                 await _errorConsumer.HandleAsync(e);
                 await HandleUndeliverable(message);
             }
         }
         else
         {
             if (!await _backlogConsumer.HandleAsync(new QueuedMessage <T>
             {
                 Attempts = attempts, Message = message
             }))
             {
                 await HandleUndeliverable(message);
             }
         }
     }
 }
예제 #3
0
        private async Task ProductionCycle(ParallelOptions options, T message, ParallelLoopState state)
        {
            var attempts = TryGetAttempts(message);

            if (state.ShouldExitCurrentIteration)
            {
                await HandleBacklog(message, attempts);

                return;
            }

            if (_errorConsumer != null)
            {
                try
                {
                    if (!await _consumer.HandleAsync(new QueuedMessage <T> {
                        Attempts = attempts, Message = message
                    }))
                    {
                        await HandleUnsuccessfulDelivery(options, message, state);

                        return;
                    }
                }
                catch (Exception e)
                {
                    await _errorConsumer.HandleAsync(e);
                    await HandleUnsuccessfulDelivery(options, message, state);

                    return;
                }
            }
            else
            {
                if (!await _consumer.HandleAsync(new QueuedMessage <T> {
                    Attempts = attempts, Message = message
                }))
                {
                    await HandleUnsuccessfulDelivery(options, message, state);

                    return;
                }
            }

            if (RetryPolicy != null)
            {
                _attempts.Remove(HashMessage(message));
            }
            Interlocked.Increment(ref _sent);
            options.CancellationToken.ThrowIfCancellationRequested();
        }
예제 #4
0
        public virtual ObservingProducer <T> Produces(IObservable <T> sequence, Action <Exception> onError = null, Action onCompleted = null)
        {
            var observer = new ActionObserver <T>(async @event => await _consumer.HandleAsync(@event), onError ?? (exception => { }), onCompleted ?? (() => { }));

            _cache.Add(observer, sequence);
            return(this);
        }
예제 #5
0
 private async Task HandleUndeliverable(T @event)
 {
     if (_undeliverableConsumer != null)
     {
         await _undeliverableConsumer.HandleAsync(@event);
     }
 }
예제 #6
0
 private async Task HandleBacklog(T @event)
 {
     if (!await _backlogConsumer.HandleAsync(@event))
     {
         await HandleUndeliverable(@event);
     }
 }
예제 #7
0
        public void Produce(Func <T> func, TimeSpan?interval = null)
        {
            if (_buffer.IsAddingCompleted)
            {
                throw new InvalidOperationException("You cannot subscribe the buffer while stopping");
            }

            func.AsContinuousObservable(interval).Subscribe(
                onNext: async x => { await Produce(x); },
                onError: async e => { if (_errorConsumer != null)
                                      {
                                          await _errorConsumer?.HandleAsync(e);
                                      }
                },
                onCompleted: () => { },
                token: _cancel.Token);
        }
예제 #8
0
        public ActionConsumer(Action <T> @delegate, IConsume <T> forwardTo)
        {
            _delegate = async @event =>
            {
                try
                {
                    @delegate(@event);

                    return(await forwardTo.HandleAsync(@event));
                }
                catch (Exception)
                {
                    return(false);
                }
            };
        }
예제 #9
0
        private async void ProductionCycle(ParallelOptions options, T @event, ParallelLoopState state)
        {
            if (state.ShouldExitCurrentIteration)
            {
                await HandleBacklog(@event);

                return;
            }

            if (!await _consumer.HandleAsync(@event))
            {
                HandleUnsuccessfulDelivery(options, @event, state);
            }

            Interlocked.Increment(ref _sent);
            options.CancellationToken.ThrowIfCancellationRequested();
        }
예제 #10
0
        private static bool Handle <T>(IConsume <T> consumer, T @event)
        {
            if (consumer is IConsumeScoped <T> before)
            {
                if (!before.Before())
                {
                    return(false);
                }
            }

            var result = consumer.HandleAsync(@event).ConfigureAwait(false).GetAwaiter().GetResult();

            if (consumer is IConsumeScoped <T> after)
            {
                result = after.After(result);
            }

            return(result);
        }
예제 #11
0
 private static bool Handle <T>(IConsume <T> consumer, T @event)
 {
     return(consumer.HandleAsync(@event).ConfigureAwait(false).GetAwaiter().GetResult());
 }
예제 #12
0
 /// <summary>
 ///     This consumer is invoked when the producer has given up on trying to deliver this message iteration.
 ///     This is the last chance consumer before the message is scrubbed from transient state.
 ///     Keep in mind that nothing stops another process from sending the same message in once it has been
 ///     finalized (sent or undeliverable) at the producer, since the hash is cleared for that message.
 ///     Hence, this provides a best effort "at least once" delivery guarantee, though you are responsible
 ///     for recovering in the event of an undelivery or failure, as the pipeline cannot make guarantees beyond
 ///     only clearing handlers that return true or reach a finalized state.
 /// </summary>
 /// <param name="consumer"></param>
 public void AttachUndeliverable(IConsume <T> consumer)
 {
     _undeliverableConsumer =
         new ActionConsumer <QueuedMessage <T> >(async x => await consumer.HandleAsync(x.Message));
 }
예제 #13
0
 /// <summary>
 ///     This consumer is invoked when the producer is stopped immediately or otherwise interrupted, as such on disposal.
 ///     Any messages still waiting to be delivered are flushed to this consumer. If the consumer reports a failure, then
 ///     the
 ///     messages are swept to the undeliverable consumer.
 /// </summary>
 public void AttachBacklog(IConsume <T> consumer)
 {
     _backlogConsumer = new ActionConsumer <QueuedMessage <T> >(async x => await consumer.HandleAsync(x.Message));
 }
예제 #14
0
        private async Task HandleUndeliverable(T @event)
        {
            await _undeliverableConsumer.HandleAsync(@event);

            Interlocked.Increment(ref _undelivered);
        }