-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Description
It may be far too late in the release cycle for this, but in writing an outline for a presentation on RxJava 2 for the last month I've come to think we're erroneously shipping two libraries as one.
RxJava 2 currently has two nearly disjoint pieces:
Flowable
andFlowableProcessor
are a Reactive StreamsPublisher
andProcessor
stream type, respectively, which use RS types for subscribing and RS types to control backpressure and unsubscribe notification.Observable
,Maybe
,Single
,Completable
, andSubject
are custom stream types which use custom types for subscribing, do not have backpressure, and use a custom type for unsubscribe notification.
Aside from explicit conversion functions between the two, these types do not interact. Observable
will soon be retrofitted to return more-specific types for certain operators. Flowable
also will receive (and already has) some of these more-specific types for certain operators as well, but unlike their enclosing type they do not support backpressure.
When you look at a high-level overview of the library like I have before for normalizing naming, you can clearly see there is a divide.
This divide seems to be rooted in the fact that there's three things pulling RxJava 2 in different directions:
- Backpressure support was added late to RxJava 1 which resulted in all operators not implementing it. The built-in factories made it harder than it should have been to create backpressure-aware observables around non-Rx sources. This caused MBEs to happen to a lot of people and the desire for non-backpressure types.
- The RS spec is to be implemented natively for backpressure-aware types.
- People use and enjoy the four specialized RxJava 1 types:
Observable
,Single
,Completable
, andSubject
, and want even more:Maybe
.
The first two of these are conflicting which is not entirely terrible. If you ignore the third item you'd get four types which we have now: Flowable
, Observable
, FlowableProcessor
, Subject
. The third item, however, starts to cause the combinatorial explosion of types.
This is what leads me to believe there are two libraries hiding inside RxJava 2 that, while related, aren't the same:
Flowable
,Maybe
-like,Single
-like,Completable
-like, andFlowableProcessor
Reactive StreamsPublisher
types.Observable
,Maybe
,Single
,Completable
, andSubject
generic non-backpressure stream types.
As far as I can tell there's three options:
- Do nothing. Ship 5 backpressure-free custom types and 2 backpressure-aware RS types in one library with built-in conversion methods across the divide. Live with the fact that the types are asymmetrical and some operators on
Flowable
do not support backpressure. - Split the library into two. They could either live inside this repository (
rxjava-rs
andrxjava-nbp
) plus an adapter library (rxjava-bridge
) for use withto()
, or they could be separate and developed/released independently. This doesn't immediately require extra types on the RS side for symmetry. They could be added as needed post-2.0.0. - Add missing types for symmetry between the two inside this one library. This might cause @akarnokd to go crazy because it's non-trivial and few else are qualified and skilled enough to do all the work. Because of the desire to customize the return types of operators it's hard to defer this to post-2.0.0 since it would break compatibility.
I'm curious to hear what others think about this. I'm sorry it didn't dawn on me as a problem sooner.
A final piece of food for thought: if you were implementing RxJava 2 as a brand new library from scratch without the historical context of RxJava 1, what would you want in it?
- Stream types that implement the Reactive Streams spec.
- Stream types that do not support backpressure.
- Customized stream types which model subsets of the event/notification lifecycle.
- Operators returning customized stream types with the correct backpressure-aware/free context.
Ideally what we ship in RxJava 2 is exactly and only the answers to that question.