Rx java 速率限制观测值

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,它从数据库游标的快速流中生成数据。我希望以每秒x个项目的速度限制输出。到目前为止,我一直在使用Callstack阻塞,如文档中所述:

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()