在玩各种背压场景时,我实现了一个用户缓慢使用缓冲区的情况,而另一个用户使用任何抛出的内容。那是使用Scala和Akka Streams。如果您愿意,可以看到代码here以及运行它的测试here。
我通常会尝试开发一个RxJava版本进行比较,但我仍然坚持这个版本。在Akka Streams中,我可以构建一个图形,其中一个源在2个通道上广播,并且具有慢速接收器和快速接收器从这些通道消耗。每个通道可以独立应用缓冲和限制。在RxJava中,有share
运算符用于广播,但缓冲和限制逻辑不在Subscriber
上,而在Observable
上。因此,我不确定如何应用缓冲和限制,并且不会影响两个订户。 Akka Streams和RxJava都是Rx的实现,我希望能够得到我想要的东西。
这是我尝试做的pictorial version。
答案 0 :(得分:1)
这样的东西?
import rx.Observable;
import rx.observables.ConnectableObservable;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) {
//emits Long every 100 milliseconds, and publishes to all Subscribers simultaneously through ConnectableObservable
ConnectableObservable<Long> source = Observable.interval(100, TimeUnit.MILLISECONDS).publish();
//buffers emissions into Lists within 1 second durations, and first Subscriber prints them
source.buffer(1,TimeUnit.SECONDS).subscribe(System.out::println);
//no buffering, just push emissions directly to this second Subscriber which prints them
source.subscribe(System.out::println);
//start firing emissions now both Subscribers are connected
source.connect();
//sleep to keep program alive for 10 seconds
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Subscriber
没有节流或任何运营商的概念。这些是在Observable
侧通过各种运算符完成的,这些运算符产生不同的Observable
实现。 Subscriber
非常愚蠢,只是消耗排放作为Observable
链中的最后一步。排放发生在哪个线程上是不可知的,更不用说Observable
将项目传递给它是否被限制。
答案 1 :(得分:0)
如果您想要不同的背压行为,您应该能够以不同的方式为不同的订阅者装饰shared()
观察者。
例如
Observable<Integer> source = Observable.interval(0, 1, TimeUnit.SECONDS).share();
// Naked source for fast consumers.
Observable<Integer> fast = source;
// Buffer for slow consumers that use backpressure.
Observable<Integer> slow = source.onBackpressureBuffer();
上述fast
和slow
的订阅者最终将使用相同的共享源。
请注意,fast
不会对背压做出响应,因为interval
不会对背压做出响应。
onBackpressureXXX()有不同的风格可以让你获得不同的行为。