使用RxJava2正确处理Backpressure和并发

时间:2018-05-22 22:01:13

标签: java design-patterns rx-java rx-java2

我有一个服务,我已经注册了一个回叫,现在我希望将其公开为具有某些要求/限制的Flowable

  1. 不应阻止线程接收回调(应将工作移交给观察者指定的其他线程/调度程序)
  2. 由于消费者放慢流量,不应该抛出任何例外
  3. 多个消费者可以彼此独立订阅
  4. 消费者可以选择缓冲所有项目,以免丢失任何项目,但不应将它们缓存在“生产者”类中
  5. 以下是我目前的

    class MyBroadcaster {
        private PublishProcessor<Packet> packets = PublishProcessor.create();
        private Flowable<Packet> backpressuredPackets = packets.onBackpressureLatest();
    
        public MyBroadcaster() {
           //this is actually different to my exact use but same conceptually
           registerCallback(packets::onNext);
        }
    
        public Flowable<Packet> observeAllPacketsOn(Scheduler scheduler) {
            return backpressuredPackets.observeOn(scheduler);
        }
    }
    

    我不确定这是否符合我的要求。关于我onBackpressureLatest的{​​{1}} javadoc有一条我不明白的说明:

      

    请注意,由于背压请求如何通过subscribeOn / observeOn传播,从下游请求多于1个并不能保证onNext事件的持续传递

    我还有其他问题:

    • observeOn来电是否会使项目不再被多播?
    • 我如何测试我的要求?
    • 奖励:如果我有多个这样的发布者(在同一个类或其他地方),那么使相同模式可重用的最佳方法是什么。使用委托/额外方法创建我自己的Flowable?

1 个答案:

答案 0 :(得分:2)

  

我不确定这是否符合我的要求。

没有。分别在onBackpressureLatestonBackpressureBuffer中应用observeOnobserveSomePacketsOn后跟observeAllPacketsOn

  

onBackpressureLatest调用是否会使项目不再被多播?

多播由PublishProcessor完成,不同的订阅者将独立建立一个频道,onBackpressureXXXobserveOn运营商在单个订阅者的基础上生效。

  

我如何测试我的要求?

使用FlowableTestSubscriber)通过有损或无损Flowable.test()订阅,将一组已知的数据包提供给packets并查看是否所有数据包都通过TestSubscriber.assertValueCount()TestSubscriber.values()。有损的应该是1 .. N而无损的应该在宽限期后有N个值。

  

奖励:如果我有多个这样的发布者(在同一个类或其他地方),那么使相同模式可重用的最佳方法是什么。使用委托/额外方法创建我自己的Flowable?

您可以将observeAllPacketsOn转换为FlowableTransformer而不是MyBroadcaster上的方法调用,请使用compose,例如:

class MyTransformers {
    public static FlowableTransformer<T, T> lossyObserveOn(Scheduler s) {
        return f -> f.onBackpressureLatest().observeOn(s);
    }
}

new MyBroadcaster().getPacketFlow()
.compose(MyTransformers.lossyObserveOn(scheduler))
.subscribe(/* ... */);