使用/不使用Rx重试tpl数据流

时间:2017-01-27 17:04:28

标签: c# tpl-dataflow rx.net

我正在使用带有TPL数据流的.net反向扩展。这是我的管道:

我从一些外部源获取数据点作为流,然后我使用数据流TransformBlocks转换数据点。在此之后,我使用Rx缓冲区缓冲流点1秒,最后我使用数据流Actionblock在REST端点上发布这些缓冲的数据点。

我想在瞬态错误上重试REST post操作。我应该在哪里重试:

  1. 缓冲后?
  2. Inside Action block?
  3. 重试时连续流式播放会发生什么?我不想错过任何数据。

1 个答案:

答案 0 :(得分:1)

刚刚提供的高级概述,我认为在最终的ActionBlock中重试是最容易的。您的ActionBlock会在结束前发布并确认成功。根据数据量的不同,这种方法可以根据需要调整尽可能多的ActionBlock,而不必过多担心丢弃的项目,实际上不应该是任何数据。如果单个或多个ActionBlock实例未通过其帖子,则您的项目仍会按照您设置缓冲区和输入队列的方式进行流式传输和分发,等待其在线路上的机会。

修改 只是一些伪代码,但这将需要一批数据点,即IEnumerable,并尝试将它们发布五次。有界容量将导致处理程序的每个实例排队1000批,并行性将在操作块之间分配批次。可选地,可以在Buffer之前添加无界ActionBlock来保存所有传入的批次。您需要注意您的生产者,流,并没有大大地运行您的消费者,REST服务。

    public void ConfigureFinalActionBlock() {
        var dataPointBuffer = new BufferBlock<IEnumerable<Datapoint>>(new DataflowBlockOptions() {
            BoundedCapacity = DataflowBlockOptions.Unbounded
        });

        var options = new ExecutionDataflowBlockOptions() {
            BoundedCapacity = 1000,
            MaxDegreeOfParallelism = Environment.ProcessorCount
        };
        var restBlock = new ActionBlock<IEnumerable<Datapoint>>(async (data) => {
            var success = false;
            var attempts = 0;
            while (!success && attempts < 5) {
                attempts++;
                success = await MyApiPostAsync(data);
            }
        }, options);

        dataPointBuffer.LinkTo(restBlock, new DataflowLinkOptions() {
            PropagateCompletion = true
        });