web-dev-qa-db-fra.com

Observable vs Flowable rxJava2

Je suis en train de regarder le nouveau rx Java 2 et je ne suis pas tout à fait sûr de comprendre l'idée de backpressure ...

Je suis conscient que nous avons Observable qui n'a pas backpressure support et Flowable qui le possède.

Donc, à titre d’exemple, disons que j’ai flowable avec interval:

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

Cela va planter après environ 128 valeurs, et c’est assez évident que je consomme plus lentement que d’obtenir des objets.

Mais alors nous avons la même chose avec 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
                }
            });

Cela ne plantera pas du tout, même si je mets un peu de temps à consommer, cela fonctionne toujours. Pour que Flowable fonctionne, disons que je mets l'opérateur onBackpressureDrop, le crash est parti mais toutes les valeurs ne sont pas émises non plus.

La question de base pour laquelle je ne trouve pas de réponse actuellement dans ma tête est: pourquoi devrais-je me préoccuper de backpressure lorsque je peux utiliser tout-aller Observable pour toujours recevoir toutes les valeurs sans gérer le buffer? Ou peut-être de l’autre côté, quels avantages backpressure me donne-t-il en faveur de la gestion et du traitement de la consommation?

110
user2141889

Ce que la contre-pression manifeste en pratique est constitué par les tampons bornés. Flowable.observeOn possède un tampon de 128 éléments qui sont drainés aussi rapidement que le flux descendant le permet. Vous pouvez augmenter cette taille de tampon individuellement pour gérer les sources éclatées. Toutes les pratiques de gestion de contre-pression s'appliquent toujours à partir de la version 1.x. Observable.observeOn dispose d'un tampon illimité qui continue à collecter les éléments et votre application risque de manquer de mémoire.

Vous pouvez utiliser Observable par exemple:

  • gestion des événements graphiques
  • travailler avec des séquences courtes (moins de 1000 éléments au total)

Vous pouvez utiliser Flowable par exemple:

  • sources froides et non synchronisées
  • générateur comme sources
  • accesseurs de réseau et de base de données
107
akarnokd

La contre-pression se produit lorsque votre observable (éditeur) crée plus d'événements que votre abonné ne peut en gérer. Ainsi, vous pouvez obtenir des événements manquants pour les abonnés ou une file d'attente énorme d'événements qui mène éventuellement à une mémoire insuffisante. Flowable prend en compte la contre-pression. Observable ne le fait pas. C'est ça.

cela me rappelle un entonnoir qui, quand il y a trop de liquide déborde. Flowable peut aider à ne pas y arriver:

avec une contrepression énorme:

enter image description here

mais avec l'utilisation de fluide, il y a beaucoup moins de contre-pression:

enter image description here

Rxjava2 a quelques stratégies de contre-pression que vous pouvez utiliser en fonction de votre cas d'utilisation. Par stratégie, je veux dire que Rxjava2 fournit un moyen de gérer les objets qui ne peuvent pas être traités à cause du débordement (contrepression).

voici les stratégies. Je ne les passerai pas toutes en revue. Par exemple, si vous souhaitez ne pas vous soucier des éléments débordés, vous pouvez utiliser une stratégie de suppression telle que celle-ci:

observable.toFlowable (BackpressureStrategy.DROP)

Autant que je sache, il devrait y avoir une limite de 128 articles dans la file d'attente, après quoi il peut y avoir un débordement (contrepression). Même si ce n'est pas son chiffre proche de ce nombre. J'espère que ça aide quelqu'un.

si vous devez modifier la taille de la mémoire tampon à partir de 128, il semble que cela puisse être fait comme ceci (mais observez les contraintes de mémoire:

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

dans le développement logiciel, une stratégie de surpression signifie généralement que vous demandez à l’émetteur de ralentir un peu car le consommateur ne peut pas gérer la vitesse de vos événements émetteurs.

88
j2emanue

Le fait que votre Flowable se soit écrasé après avoir émis 128 valeurs sans traitement de la contre-pression ne signifie pas qu'il se plantera toujours exactement après 128 valeurs. Je crois que c’est ce qui s’est passé lorsque vous avez essayé l’exemple avec Observable - il n’y avait aucune dépression, donc votre code a fonctionné normalement. La différence dans RxJava 2 est qu’il n’existe plus de notion de contre-pression dans Observables, et qu’il n’existe aucun moyen de le gérer. Si vous concevez une séquence réactive qui nécessitera probablement une gestion explicite de la contre-pression, alors Flowable est votre meilleur choix.

14
Egor