Спостерігається проти Flowable rxJava2


128

Я дивився на новий rx java 2, і я не зовсім впевнений, що більше розумію ідею backpressure...

Я усвідомлюю, що ми маємо, Observableщо не має backpressureпідтримки, і Flowableце має її.

Так на основі , наприклад, дозволяє сказати , що у мене є flowableз 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
                }
            });

Це стане крахом після приблизно 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дають мені на користь управління та поводження з спожиючим?


Відповіді:


123

Те, що протилежний прояв на практиці є обмеженими буферами, Flowable.observeOnмає буфер із 128 елементів, який стікає так швидко, як нижчий потік може його прийняти. Ви можете збільшувати цей розмір буфера окремо, щоб обробляти джерело розриву, і всі практики управління тиском все ще застосовуються з 1.x. Observable.observeOnмає необмежений буфер, який продовжує збирати елементи, і у вашої програми може не вистачати пам'яті.

Ви можете використовувати, Observableнаприклад:

  • обробка графічних подій GUI
  • робота з короткими послідовностями (менше 1000 елементів)

Ви можете використовувати, Flowableнаприклад:

  • холодні та несвоєчасні джерела
  • генератор як джерела
  • мережеві та бази даних

Так як це придумав інше питання - це правильно , що більш обмежені типи , як Maybe, Singleі Completableможе завжди використовуватися замість того , щоб, Flowableколи вони семантично відповідні?
david.mihola

1
Так, Maybe, Singleі Completableє далеко надто малі , щоб мати якийсь - або необхідності концепції противодавления. Немає шансів, що виробник може випустити товари швидше, ніж їх можна буде споживати, оскільки 0–1 предметів колись буде виготовлено або спожито.
AndrewF

Можливо, я не правий, але для мене приклади плаваючого та спостережуваного слід міняти місцями.
Юра Галавай

Я думаю, що у запитанні він відсутній стратегії зворотного тиску, яку нам потрібно надати Flowable, яка пояснює, чому викинутий виняток протитиску викидається, а також пояснює, чому цей виняток зникає після його застосування .onBackpressureDrop (). А для спостережуваного, оскільки у нього немає цієї стратегії і її неможливо надати, вона пізніше буде просто невдалою через OOM
Haomin

111

Зворотний тиск - це коли ваш спостережуваний (видавець) створює більше подій, ніж може перешкоджати ваш підписник. Таким чином, ви можете отримати абонентів, що пропускають події, або ви можете отримати величезну чергу подій, яка просто призводить до виходу з пам'яті. Flowableвраховує зворотний тиск. Observableне. Це воно.

це нагадує мені воронку, яка, коли в неї занадто багато рідини переливається. Flowable може допомогти не допустити цього:

з величезним тиском:

введіть тут опис зображення

але при використанні плавного потоку набагато менший тиск:

введіть тут опис зображення

Rxjava2 має кілька стратегій зворотного тиску, які ви можете використовувати залежно від вашої сфери використання. під стратегією я маю на увазі, що Rxjava2 забезпечує спосіб обробки об'єктів, які не можуть бути оброблені через переповнення (зворотний тиск).

ось стратегії. Я не буду переглядати їх усі, але, наприклад, якщо ви хочете не турбуватися про переповнені елементи, ви можете скористатися такою стратегією краплі:

observable.toFlowable (BackpressureStrategy.DROP)

Наскільки я знаю, у черзі має бути обмеження на 128 пунктів, після цього може бути переповнення (зворотний тиск). Навіть якщо його не 128, це близько до цього числа. Сподіваюся, що це комусь допоможе.

якщо вам потрібно змінити розмір буфера з 128, схоже, це можна зробити так (але слідкуйте за будь-якими обмеженнями пам’яті:

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

в розробці програмного забезпечення зазвичай стратегія зворотного тиску означає, що ви говорите емітеру трохи сповільнитись, оскільки споживач не може впоратися зі швидкістю ваших випромінюючих подій.


Я завжди думав, що резервний тиск - це назва сімейства механізмів, які дозволять споживачу сповістити виробника сповільнитись ...
kboom

Може бути так. Так
j2emanue

Чи є якісь недоліки використання Flowable?
ІгорГанапольський

Ці образи мене брешуть. Відмова від подій не закінчиться "більше грошей" внизу.
EpicPandaForce

1
@ j2emanue, ви плутаєте розмір буфера для операторів і оператора Flowable.buffer (int). Будь ласка, читайте javadocs кафезно і виправте відповідь відповідно: reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html
tomek

15

Той факт, що ваш Flowableзбій після передачі 128 значень без обробки тиску не означає, що він завжди вийде з ладу після точно 128 значень: іноді він вийде з ладу після 10, а іноді і зовсім не вийде з ладу. Я вважаю, що це сталося, коли ви спробували приклад з Observable- не сталося зворотного тиску, тому ваш код працював нормально, наступного разу він може не статися. Різниця RxJava 2 полягає в тому, що в Observables вже немає концепції протитиску , і немає способу впоратися з цим. Якщо ви розробляєте реакційну послідовність, яка, ймовірно, потребує явної обробки тиску, - Flowableце ваш найкращий вибір.


Так, я зауважував, що іноді він порушується після менших значень, іноді - ні. Але знову ж таки, якщо, наприклад, я поводжусь лише intervalбез того, backpressureчи сподіваюся я на якусь дивну поведінку чи проблеми?
користувач2141889

Якщо ви впевнені, що у певній послідовності, що спостерігається, не може виникнути проблем із тиском - тоді, мабуть, добре ігнорувати зворотний тиск.
Єгор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.