RxJava2 có thể quan sát và có thể lưu chuyển


128

Tôi đã xem xét rx java 2 mới và tôi không chắc mình hiểu ý tưởng của backpressurenữa ...

Tôi biết rằng chúng tôi có Observablemà không có backpressurehỗ trợ và Flowablecó nó.

Vì vậy, dựa trên ví dụ, giả sử tôi có flowablevới 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
                }
            });

Điều này sẽ gặp sự cố sau khoảng 128 giá trị và điều đó khá rõ ràng là tôi đang tiêu thụ chậm hơn so với việc nhận các vật phẩm.

Nhưng sau đó chúng ta có cùng với 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
                }
            });

Điều này sẽ không xảy ra sự cố nào cả, ngay cả khi tôi đặt một chút trì hoãn vào việc tiêu thụ nó vẫn hoạt động. Để thực hiện Flowablecông việc, giả sử tôi đặt onBackpressureDroptoán tử, sự cố đã biến mất nhưng không phải tất cả các giá trị cũng được phát ra.

Vì vậy, câu hỏi cơ bản mà tôi không thể tìm thấy câu trả lời hiện trong đầu là tại sao tôi phải quan tâm đến việc backpressurekhi tôi có thể sử dụng thuần túy Observablevẫn nhận được tất cả các giá trị mà không cần quản lý buffer? Hoặc có thể từ phía khác, những lợi thế nào backpressuremang lại cho tôi trong việc quản lý và xử lý việc tiêu thụ?


Câu trả lời:


123

Những gì áp suất ngược biểu hiện trong thực tế là bộ đệm giới hạn, Flowable.observeOncó bộ đệm gồm 128 phần tử được thoát nhanh như dòng xuống có thể lấy nó. Bạn có thể tăng kích thước bộ đệm này riêng lẻ để xử lý nguồn bursty và tất cả các phương pháp quản lý áp suất ngược vẫn được áp dụng từ 1.x. Observable.observeOncó bộ đệm không giới hạn giúp tiếp tục thu thập các phần tử và ứng dụng của bạn có thể hết bộ nhớ.

Bạn có thể sử dụng Observableví dụ:

  • xử lý các sự kiện GUI
  • làm việc với các chuỗi ngắn (tổng số ít hơn 1000 phần tử)

Bạn có thể sử dụng Flowableví dụ:

  • nguồn lạnh và không hẹn giờ
  • máy phát điện như nguồn
  • người truy cập mạng và cơ sở dữ liệu

Vì đây có đưa ra trong một câu hỏi khác - là nó đúng rằng các loại hạn chế giống như Maybe, SingleCompletablecó thể luôn luôn được sử dụng thay vì Flowablekhi họ đang thích hợp ngữ nghĩa?
david.mihola

1
Vâng, Maybe, Single, và Completablexa quá nhỏ để có bất cứ nhu cầu của khái niệm backpressure. Không có cơ hội nào để một nhà sản xuất có thể phát ra các vật phẩm nhanh hơn mức tiêu thụ được, vì từ 0–1 vật phẩm sẽ được sản xuất hoặc tiêu thụ.
AndrewF

Có thể tôi không đúng, nhưng đối với tôi Ví dụ về Flowable và Observable nên được hoán đổi.
Yura Galavay

Tôi nghĩ rằng trong câu hỏi, anh ta đang thiếu chiến lược áp suất ngược mà chúng ta cần cung cấp cho Flowable, điều này giải thích tại sao ngoại lệ áp suất ngược bị thiếu được ném ra, cũng giải thích tại sao ngoại lệ này biến mất sau khi anh ta áp dụng .onBackpressureDrop (). Và đối với Observable, vì nó không có chiến lược này và không thể được cung cấp, nó sẽ đơn giản là thất bại sau đó do
OOM

111

Áp suất ngược là khi (nhà xuất bản) có thể quan sát của bạn đang tạo ra nhiều sự kiện hơn mức người đăng ký của bạn có thể xử lý. Vì vậy, bạn có thể khiến người đăng ký bỏ lỡ sự kiện hoặc bạn có thể nhận được hàng đợi sự kiện khổng lồ dẫn đến hết bộ nhớ. Flowablecân nhắc áp suất ngược. Observablekhông làm. Đó là nó.

nó làm tôi liên tưởng đến một cái phễu khi nó có quá nhiều chất lỏng tràn ra ngoài. Flowable có thể giúp không làm điều đó xảy ra:

với áp suất ngược cực lớn:

nhập mô tả hình ảnh ở đây

nhưng với việc sử dụng có thể chảy, áp suất ngược ít hơn nhiều:

nhập mô tả hình ảnh ở đây

Rxjava2 có một số chiến lược áp suất ngược mà bạn có thể sử dụng tùy thuộc vào usecase của mình. theo chiến lược, ý tôi là Rxjava2 cung cấp một cách để xử lý các đối tượng không thể xử lý được do tràn (áp suất ngược).

đây là các chiến lược. Tôi sẽ không xem qua tất cả, nhưng ví dụ: nếu bạn muốn không lo lắng về các mục bị tràn, bạn có thể sử dụng chiến lược thả như sau:

Observable.toFlowable (BackpressureStrategy.DROP)

Theo như tôi biết phải có giới hạn 128 mặt hàng trên hàng đợi, sau đó có thể có tràn (áp suất ngược). Ngay cả khi nó không phải là 128 của nó gần với con số đó. Hy vọng điều này sẽ giúp ai đó.

nếu bạn cần thay đổi kích thước bộ đệm từ 128, có vẻ như nó có thể được thực hiện như thế này (nhưng hãy xem bất kỳ hạn chế bộ nhớ nào:

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

trong phát triển phần mềm, chiến lược áp lực ngược thường có nghĩa là bạn yêu cầu bộ phát chạy chậm lại một chút vì người tiêu dùng không thể xử lý tốc độ các sự kiện phát ra của bạn.


Tôi luôn luôn nghĩ rằng backpressure là tên cho một gia đình của các cơ chế đó sẽ cho phép người tiêu dùng thông báo cho nhà sản xuất để làm chậm ...
KBOOM

Có thể là trường hợp. Có
j2emanue

Có bất kỳ nhược điểm nào khi sử dụng Flowable không?
IgorGanapolsky

Những hình ảnh này đang nói dối tôi. Bỏ sự kiện sẽ không kết thúc với "nhiều tiền hơn" ở phía dưới.
EpicPandaForce

1
@ j2emanue, bạn đang nhầm lẫn giữa kích thước bộ đệm cho toán tử và toán tử Flowable.buffer (int). Xin vui lòng đọc các javadocs cafefully và sửa chữa câu trả lời của bạn cho phù hợp: reactivex.io/RxJava/2.x/javadoc/io/reactivex/Flowable.html
Tomek

15

Thực tế là sự Flowablecố của bạn sau khi tạo ra 128 giá trị mà không xử lý áp suất ngược không có nghĩa là nó sẽ luôn bị lỗi sau chính xác 128 giá trị: đôi khi nó sẽ bị lỗi sau 10 và đôi khi nó không bị lỗi gì cả. Tôi tin rằng đây là những gì đã xảy ra khi bạn thử ví dụ với Observable- tình cờ không có áp suất ngược, vì vậy mã của bạn hoạt động bình thường, lần sau có thể không. Sự khác biệt trong RxJava 2 là không có khái niệm về áp suất ngược trong Observables nữa và không có cách nào để xử lý nó. Nếu bạn đang thiết kế một chuỗi phản ứng có thể sẽ yêu cầu xử lý áp suất ngược rõ ràng - thì đây Flowablelà lựa chọn tốt nhất của bạn.


Có, tôi đã quan sát thấy rằng đôi khi nó bị phá vỡ sau khi giá trị thấp hơn, đôi khi nó không. Nhưng một lần nữa, nếu ví dụ như tôi chỉ xử lý intervalmà không backpressurecó tôi có mong đợi một số hành vi hoặc vấn đề kỳ lạ không?
user2141889

Nếu bạn chắc chắn rằng không có cách nào các vấn đề áp suất ngược có thể xảy ra trong một trình tự Có thể quan sát cụ thể - thì tôi đoán là tốt để bỏ qua áp suất ngược.
Egor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.