创建像环缓冲区一样批处理的Observable(需要建议)

时间:2015-11-17 14:57:49

标签: java reactive-programming rx-java disruptor-pattern

在找到here所描述的问题没有找到合适的解决方案后,我决定实施此问题。

但是我缺乏使用monad的经验,而像lift(..)这样的东西对我来说仍然看起来有些神奇......

我打开这个的目的是让那些在rxjava之上实现一些自定义内容的人可以就如何实现这一点给我建议。

现在这是什么,这是界面。

enter image description here

我认为这对大多数人来说都是不言自明的,但我要确定我会举一个例子。

想象一下,我们有一个订户(消费者)实际上坚持数据库,很明显,如果你给它1或1000个对象来保持差异不会是因子1000它将是10倍或更少,这意味着它是一个可以采用加载的消费者...所以一次推送一个项目是愚蠢的,而你可以一次坚持多个,另一方面它是愚蠢的等待一些N元素来填补直到你坚持(一秒钟,你可能会得到1000个元素,你可能得不到,所以假设我们不知道传入数据的频率是多少)......

所以我们现在所拥有的是Observable.batch(),它会要求批量的N大小,我们经常会在没有工作的情况下等待...另一方面我们有Disruptor这正是我们所做的希望但不提供Observable的漂亮界面...... Disruptor将处理单个元素,当您处理它时,它将收集所有传入的元素,并在下次您获得批量的所有内容时因为您的消费者忙于最后一个值而收集的信息......

目前我认为我将使用Observable.from()来实现此目的或lift() ...

请分享您对此的看法,也许已经有解决方案可用,我不知道,或者我要以错误的方式实现这一点......

2 个答案:

答案 0 :(得分:4)

这是一个运算符,它将批量堆积在异步边界后面的值:

ConnectableObservable

但是,请注意,您在API中描述的是一种热门Observable:冷源不会跨多个订阅者进行协调。为此,您需要创建自定义publish()

disruptForEachSubscriber可能适用于publish().observeOn()disruptForAllSubscriber observeOn可能不适用{1}},因为publish会请求一堆值而{{1}}会将其解释为N批次的成功处理。

答案 1 :(得分:1)

这不是一个答案(akarnokd已经给了一个很棒的答案),只是一个更长的评论。

这是一个我觉得非常有用的算子。每当我有热源和慢用户时,我都会使用它 - 我使用一些聚合策略来聚合在消费期间堆积的事件,并使用聚合结果。

示例:

  • 反应式绘图库。用户移动鼠标,拖动绘图,但渲染速度很慢,因此我在渲染新版本之前聚合用户的操作
  • 再次绘图,这次显示通过TCP / IP从服务器延迟获取的数据。当用户显示长图的新部分时,正在生成对服务器的新数据的请求。在发送新的TCP请求数据包之前,我将所有请求合并为一个。
  • ObserveLatestOn是此问题的更具体版本,其中"聚合"只是采取最后一个元素。

在C#世界中,此运算符称为BufferIntrospective。我已经设法使用zxswing's help编写了我自己的版本,但是一旦我有时间,我肯定会查看此代码。

我的实现中略有不同的一点是,我的变体还有一个参数sendFinalBufferedItemsBeforeCompletion: Boolean,它指定了取消订阅行为的外观。在true时,它会发送最后一批在OnComplete之前累积的项目,当false时,它会立即OnComplete。对于我的用例,两种用法都有意义。