private Action <DeliveryReport <K, V> > BuildSendCallback <TResult>(TaskCompletionSource <TResult> completion, Action <DeliveryReport <K, V> > onSuccess)
        {
            return(report =>
            {
                if (!report.Error.IsError)
                {
                    onSuccess(report);
                }
                else
                {
                    Log.Error(report.Error.Reason);
                    var exception = new KafkaException(report.Error);
                    switch (_decider(exception))
                    {
                    case Directive.Stop:
                        if (_stage.CloseProducerOnStop)
                        {
                            // TODO: address the missing Producer.Close() in the future
                            Producer.Dispose();
                        }
                        _failStageCallback(exception);
                        break;

                    default:
                        completion.SetException(exception);
                        break;
                    }
                }

                if (AwaitingConfirmation.DecrementAndGet() == 0 && _inIsClosed)
                {
                    _checkForCompletionCallback();
                }
            });
        }
Exemplo n.º 2
0
        public ProducerStageLogic(ProducerStage <K, V> stage, Attributes attributes) : base(stage.Shape)
        {
            _stage = stage;

            var supervisionStrategy = attributes.GetAttribute <ActorAttributes.SupervisionStrategy>(null);
            var decider             = supervisionStrategy != null ? supervisionStrategy.Decider : Deciders.ResumingDecider;

            SetHandler(_stage.In,
                       onPush: () =>
            {
                var msg    = Grab(_stage.In);
                var result = new TaskCompletionSource <DeliveryReport <K, V> >();

                _producer.Produce(msg.TopicPartition, msg.Message, report =>
                {
                    if (!report.Error.HasError)
                    {
                        result.SetResult(report);
                    }
                    else
                    {
                        var exception = new KafkaException(report.Error);
                        switch (decider(exception))
                        {
                        case Directive.Stop:
                            if (_stage.CloseProducerOnStop)
                            {
                                _producer.Dispose();
                            }
                            FailStage(exception);
                            break;

                        default:
                            result.SetException(exception);
                            break;
                        }
                    }

                    if (_awaitingConfirmation.DecrementAndGet() == 0 && _inIsClosed)
                    {
                        CheckForCompletion();
                    }
                });

                _awaitingConfirmation.IncrementAndGet();
                Push(_stage.Out, result.Task);
            },
                       onUpstreamFinish: () =>
            {
                _inIsClosed = true;
                _completionState.SetResult(NotUsed.Instance);
                CheckForCompletion();
            },
                       onUpstreamFailure: exception =>
            {
                _inIsClosed = true;
                _completionState.SetException(exception);
                CheckForCompletion();
            });

            SetHandler(_stage.Out, onPull: () =>
            {
                TryPull(_stage.In);
            });
        }