Rx java 速率限制观测值
我有一个observable,它从数据库游标的快速流中生成数据。我希望以每秒x个项目的速度限制输出。到目前为止,我一直在使用Callstack阻塞,如文档中所述:Rx java 速率限制观测值,rx-java,Rx Java,我有一个observable,它从数据库游标的快速流中生成数据。我希望以每秒x个项目的速度限制输出。到目前为止,我一直在使用Callstack阻塞,如文档中所述: observable.map(f -> { ratelimiter.acquire(); // configured limiter to only allow }); 这很好,但只是出于好奇,有没有更好的方法来处理这个使用背压 Tks使用示例(throttleLast)运算符: Observable<T> thr
observable.map(f -> {
ratelimiter.acquire(); // configured limiter to only allow
});
这很好,但只是出于好奇,有没有更好的方法来处理这个使用背压
Tks使用示例
(throttleLast)运算符:
Observable<T> throttled =
observable.sample(1 / rate, TimeUnit.MILLISECONDS);
Observable throttled=
可观察样本(1/速率,时间单位毫秒);
您可以尝试使用
rx.Observable#onBackpressureBuffer()
与自定义订户组合使用,该订户每秒将定期请求n
项。但是,您必须进行一秒钟的采样
注意.subscribeOn()
和.toBlocking()
只是为了使主方法不会立即退出
公共类背压测试{
公共静态void main(最终字符串[]args){
可观测范围(11000)
.compose(Observable::onBackpressureBuffer)//立即使用源,但缓冲它
.lift(allowPerSecond(3))//通过操作员使用自定义订户请求每秒n项
.subscribeOn(Schedulers.computation())
.toBlocking()
.subscribe(System.out::println);
}
私有静态可观测。运算符allowPerSecond(最终整数n){
返回上游->周期性请求订户(上游,n);
}
专用静态订户periodicallyRequestingSubscriber(最终订户上游,最终整数n){
返回新订户(){
@凌驾
public void onStart(){
请求(0);//请求0以使源停止发射
可观察。间隔(1秒)。订阅(x->请求(n));//每秒请求n个项目
}
@凌驾
未完成的公共无效(){
上游。未完成();
}
@凌驾
公共作废申报人(最终可丢弃e){
上游。onError(e);
}
@凌驾
public void onNext(最终T整数){
onNext(整数);
}
};
}
}
来自@michalsamek的答案似乎是正确的,尽管背压仅适用于流动性。我已经更正了他的订户,所以它可以按要求执行
在不同的时间使用它时也有一个小问题
private static <T> FlowableOperator<T, T> allowPerMillis(int millis) {
return observer -> new PeriodicallyRequestingSubscriber<>(observer, millis);
}
Observable.range(1, 100)
.observeOn(Schedulers.io())
.toFlowable(BackpressureStrategy.BUFFER)
.compose(Flowable::onBackpressureBuffer)
.lift(allowPerMillis(200))
.subscribe(value -> System.out.println(System.currentTimeMillis() % 10_000 + " : " + value));
public class PeriodicallyRequestingSubscriber<T> implements Subscriber<T> {
private final Subscriber<T> upstream;
private final int millis;
// If there hasn't been a request for a long time, do not flood
private final AtomicBoolean shouldRequest = new AtomicBoolean(true);
public PeriodicallyRequestingSubscriber(Subscriber<T> upstream, int millis) {
this.upstream = upstream;
this.millis = millis;
}
@Override
public void onSubscribe(Subscription subscription) {
Observable
.interval(millis, TimeUnit.MILLISECONDS)
.subscribe(x -> {
if (shouldRequest.getAndSet(false))
subscription.request(1);
});
}
@Override
public void onNext(T t) {
shouldRequest.set(true);
upstream.onNext(t);
}
@Override
public void onError(Throwable throwable) {
upstream.onError(throwable);
}
@Override
public void onComplete() {
upstream.onComplete();
}
}
private static FlowableOperator allowPerMillis(int millis){
返回观察者->新的周期性要求订阅者(观察者,毫秒);
}
可观测范围(1100)
.observeOn(Schedulers.io())
.toFlowable(背压等级缓冲器)
.compose(可流动::onBackpressureBuffer)
.升降机(allowPerMillis(200))
.subscribe(value->System.out.println(System.currentTimeMillis()%10_000+“:“+value));
公共类PeriodicallyRequestingSubscriber实现Subscriber{
专用最终用户上行;
私人最终整数毫秒;
//如果很长一段时间没有请求,请不要泛滥
private final AtomicBoolean shouldRequest=新AtomicBoolean(true);
公共周期AllyRequestingSubscriber(订户上游,整数毫秒){
这个。上游=上游;
这个.millis=millis;
}
@凌驾
认购时的公共作废(认购){
可观察
.间隔(毫秒,时间单位.毫秒)
.订阅(x->{
if(shouldRequest.getAndSet(false))
认购请求书(1);
});
}
@凌驾
下一页(T){
shouldRequest.set(true);
上游.onNext(t);
}
@凌驾
公共作废登记员(可丢弃){
上游。onError(可丢弃);
}
@凌驾
未完成的公共空间(){
onComplete();
}
}
您想要'delay'还是throttleFirst(throttleLast)
?如果接收项目太快,后者将删除项目。sample
将删除数据,我认为Vinicius不需要这些数据。.compose(Flowable::onBackpressureBuffer)
需要什么?您不能直接调用.onBackpressureBuffer()
?需要什么.compose(Flowable::onBackpressureBuffer)
?你不能直接调用.onBackpressureBuffer()
?