web-dev-qa-db-ja.com

観測可能vs流動可能rxJava2

私は新しいrx Java 2を見てきましたが、backpressureのアイデアをもう理解しているかどうかはわかりません...

Observableをサポートしていないbackpressureをサポートしており、Flowableをサポートしていることを認識しています。

例に基づいて、flowableintervalがあるとしましょう。

        Flowable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

これは、約128の値の後にクラッシュします。これは、アイテムを取得するよりも時間がかかることは明らかです。

しかし、それからObservableでも同じことができます

     Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

これを使用するのに多少の遅延をかけたとしても、これはまったくクラッシュしません。 Flowableを機能させるには、onBackpressureDrop演算子を使用すると、クラッシュはなくなりますが、すべての値が出力されるわけではありません。

だから、現在私の頭の中に答えが見つからない基本的な質問は、なぜbackpressureを管理せずにプレーンなObservableをまだ使用できるのにbufferを気にする必要があるのか​​ということです。あるいは、反対側から、backpressureが消費の管理と処理に有利になるメリットは何ですか?

110
user2141889

バックプレッシャーが実際に現れるのは、境界バッファです。Flowable.observeOnは、128個の要素からなるバッファを持っています。バッファは、ダウストリームがそれを処理できるのと同じくらい速く排出されます。あなたはバースト的なソースを扱うためにこのバッファサイズを個別に増やすことができ、すべてのバックプレッシャ管理プラクティスはまだ1.xから適用されます。 Observable.observeOnには、要素を収集し続ける無制限のバッファがあり、アプリのメモリが不足する可能性があります。

例えばObservableを使うことができます。

  • gUIイベントの処理
  • 短いシーケンスで作業する(合計1000エレメント未満)

例えばFlowableを使うことができます。

  • 寒くて時限のないソース
  • ジェネレータのようなソース
  • ネットワークとデータベースのアクセサ
101
akarnokd

バックプレッシャは、あなたの監視可能者(パブリッシャ)があなたの加入者が処理できるよりも多くのイベントを作成しているときです。ですから、購読者にイベントを見逃してもらうことも、イベントの巨大なキューを取得して、結果的にメモリ不足になることもできます。 Flowableは背圧を考慮に入れます。 Observableはそうではありません。それでおしまい。

それはあまりにも多くの液体があるときにあふれる漏斗を私に思い出させます。 Flowableは、それが起こらないようにするのに役立ちます。

途方もない背圧を持つ:

enter image description here

しかし、flowableを使用すると、背圧がはるかに少なくなります。

enter image description here

Rxjava2には、ユースケースに応じて使用できる背圧戦略がいくつかあります。戦略によって、Rxjava2はオーバーフロー(背圧)のために処理できないオブジェクトを処理する方法を提供します。

ここに戦略があります 私はそれらすべてを見ていきませんが、例えばあなたがあふれているアイテムについて心配したくないなら、あなたはこのような落下戦略を使うことができます:

observable.toFlowable(BackpressureStrategy.DROP)

私が知っている限りでは、キューには128アイテムの制限があるはずです。その後、オーバーフロー(バックプレッシャー)が発生する可能性があります。 128でなくてもその数に近い。これが誰かに役立つことを願っています。

あなたが128からバッファサイズを変更する必要があるならば、それはそれがこのようにすることができるように見えます(しかし、どんなメモリ制約にも注意してください:

myObservable.toFlowable(BackpressureStrategy.MISSING).buffer(256); //but using MISSING might be slower.  

ソフトウェア開発では通常バックプレッシャー戦略は、消費者があなたの放出イベントを処理することができないので、あなたがエミッタに少し遅くするように言うことを意味します。

83
j2emanue

あなたのFlowableがバックプレッシャ処理なしで128個の値を出力した後にクラッシュしたという事実は、それが常に128個の値の後でクラッシュするという意味ではありません。これはObservableで例を試したときに起こったことだと思います - たまたまバックプレッシャーがなかったので、あなたのコードは正常に機能しましたが、次回は機能しませんでした。 RxJava 2の違いは、Observablesには背圧の概念がなくなり、それを処理する方法がなくなったことです。おそらく明示的なバックプレッシャ処理を必要とするリアクティブシーケンスを設計しているのであれば - Flowableがあなたの最良の選択です。

14
Egor