Rxjava: 3.x: Single or split library.

Created on 26 Sep 2017  路  8Comments  路  Source: ReactiveX/RxJava

RxJava 2 is quite a beast with several foundational types (Flowable, ParallelFlowable, Observable, Single, Maybe, Completable) with extensive API surfaces and considerable jar file size.

Arguments for splitting:

  • Less conceptional weight due to the backpressure/no-backpressure difference between them.
  • Flow-supporting parts, such as Disposable, Scheduler, SimpleQueue and other support can be factored out.
  • Smaller download size.

Arguments against:

  • RxJava 2 ProGuards quite well
  • The need to introduce 4 artifacts: common, flowable, observable, interop. The interop is required as the flowable and observable can no longer reference each other.
  • Should they share the same version or have independent versions?
3.x Discussion

Most helpful comment

I vote for not splitting for now.

Potential issues of splitting:

  • Users will sometimes pull different component versions into single project and have complicated compatibility issues (because of transitive deps for instance) and we'll see issues here and questions on StackOverflow about that. It happens with Kotlin (different reflection-lib revision is particularly hard to figure out), it happens with Android support library (there is even a Lint rule that checks that now) & other projects, and it's painful
  • It will make interop between rx types painful for Java users, they'll have to use static methods. It's RxJava, we have to think about Java users
  • It raises a valid question of splitting observable into observable, single, maybe, completable, but interop for Java will be even more painful then
  • If observable artifact will be much more popular than flowable, then it will potentially make RxJava more independent from Reactive Streams Spec (as 1.x was) which can lead to feature requests and internal changes that'll be even less compatible with the spec and make maintenance harder
  • "Less conceptional weight" will most likely become "More conceptional weight", because user will have to figure out which part of RxJava to use, how to interop and so on. People already misuse RxAndroid/RxKotlin/etc, split inside RxJava itself will make it even worse

All 8 comments

Less conceptional weight due to the backpressure/no-backpressure difference between them.

I'm not completely sure I agree with this. Right now you can simply drop RxJava into a project and start learning. If you split the library, new users will need to understand, or at least be aware of, backpressure before they can even pick which artifacts to bring into their build. The alternate scenario I see is just importing all artifacts into a project before understanding the differences between non-backpressure and backpressure operators, which somewhat goes against the reasoning of less conceptual weight.

The other benefits (such as a smaller size) would be nice, however. Not everything is proguarded and multidex is still something a lot of Android teams avoid.

It's possible to generate an extra artifact all-in-one that will contain all other artifacts. It gives the flexibility to use the library like version 2.x or in the more granular way.

I'd vote for splitting unless there are cases where there would be a lot of code duplication. Proguarding well is a great asset, but nothing will beat simply not having the code there.

I vote for not splitting for now.

Potential issues of splitting:

  • Users will sometimes pull different component versions into single project and have complicated compatibility issues (because of transitive deps for instance) and we'll see issues here and questions on StackOverflow about that. It happens with Kotlin (different reflection-lib revision is particularly hard to figure out), it happens with Android support library (there is even a Lint rule that checks that now) & other projects, and it's painful
  • It will make interop between rx types painful for Java users, they'll have to use static methods. It's RxJava, we have to think about Java users
  • It raises a valid question of splitting observable into observable, single, maybe, completable, but interop for Java will be even more painful then
  • If observable artifact will be much more popular than flowable, then it will potentially make RxJava more independent from Reactive Streams Spec (as 1.x was) which can lead to feature requests and internal changes that'll be even less compatible with the spec and make maintenance harder
  • "Less conceptional weight" will most likely become "More conceptional weight", because user will have to figure out which part of RxJava to use, how to interop and so on. People already misuse RxAndroid/RxKotlin/etc, split inside RxJava itself will make it even worse

Another reason for not splitting (maybe not a good one) if the module share package space it can cause problems with Java 9. (See the current JSR 305 problems)

Is "users may be confused" is a valid argument? Oracle used that argument for more than a decade, and then spent close to 5 years and God knows how much money in splitting a jar. Java's biggest issue is backward compatibility crap (case in point, Thread.stop deprecated in Java 1.1 and still exists in the API), and just because RxJava has the same word in it's name, it's probably not a good enough reason to inherit the same evil.

cut-the-anchor-loose

I am not a huge fan of "backward compatibility" for Generics support, so they implemented Type Erasures because it is developer headaches.

I decided the library won't be split in 3.x due to an excessive amount of additional maintenance costs. The moment Java adds extension methods, this split can be revisited again.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

midnight-wonderer picture midnight-wonderer  路  3Comments

francorolando picture francorolando  路  3Comments

perlow picture perlow  路  3Comments

aballano picture aballano  路  3Comments

dimsuz picture dimsuz  路  4Comments