Releases: ReactiveX/RxJava
1.3.0
Summary
Version 1.3.0 is the next minor release of the 1.x series of RxJava containing many formerly experimental API components promoted to standard. Most notably the Completable base reactive type is now standard as well.
Note that the experimental rx.Observable.fromEmitter() has been removed in favor for the now also standard Observable.create(Action1<Emitter<T>> emitter, Emitter.BackpressureMode backpressure)
The planned lifecycle of the 1.x line is as follows:
| Date | Remark |
|---|---|
| June 1, 2017 | Feature freeze, only bugfixes from this on. |
| September 1, 2017 | Release 1.4.0 finalizing the remaining API components. |
| March 31, 2018 | End of development. |
The following components have been promoted to standard:
Classes, interfaces
- classes:
AssemblyStackTraceException,RxJavaCompletableExecutionHook,RxJavaHooks,UnicastSubject,BlockingSingle,Completable,AssertableSubscriber,AsyncCompletableSubscriber,SafeCompletableSubscriber - interfaces:
Cancellable,Emitter,SingleEmitter,CompletableEmitter,CompletableSubscriber,BackpressureOverflow.Strategy
Operators
Observable:create,unsafeCreate,to,zip(Observable[], FuncN),flatMapCompletable,flatMapSingle,groupby(Func1, Func1, Func1<Action1<K>, Map<K, Object>>),onTerminateDetach,rebatchRequests,subscribeOn(Scheduler, boolean),sorted,withLatestFrom,test,toCompletable,concatDelayError,mergeDelayError,switchOnNextDelayError,using(Func0, Func1, Action1, boolean),concatMapDelayError,delaySubscription(Observable),distinctUntilChanged(Func2),concatEager,concatMapEager,onBackpressureBuffer(long, Action0, BackpressureOverflow.Strategy),switchMapDelayError,toSortedList(int),toSortedList(Func2, int)Completable:fromEmitter,testSingle:fromEmitter,merge,mergeDelayError,cache,to,doOnEach,doOnSuccess,test,onErrorResumeNext,toCompletable,doOnError,doOnSubscribe,delay,defer,doOnUnsubscribe,doAfterTerminate,flatMapCompletable,lift,toBlocking,using,delaySubscription(Observable)TestSubscriber:getCompletions,awaitValueCount,assertValuesAndClearSyncOnSubscriber:createSingleState,createStateful,createStateless
Other
Schedulers.resetCompositeException(Throwable...)constructorExceptions.throwOrReport(4 overloads)BlockingObservable.subscribe(6 overloads)RxJavaSchedulersHook:createComputationScheduler,createIoScheduler,createNewThreadScheduler- internal:
AssertableSubscriberObservable,FlatMapCompletable,FlatMapSingle,SchedulerWhen,BackpressureDrainManager,BlockingUtils. RxJavaPlugins:reset,getCompletableExecutionHook,registerCompletableExecutionHookRxJavaErrorHandler:handleOnNextValueRendering,render
In addition, the class AsyncOnsubscribe with its 7 factory methods and Observable.create(AsyncOnSubscribe<S, T>) have been promoted to beta.
Acknowledgements
Thanks to all who contributed to the 1.x line in the past 6 months (in order they appear on the commit page):
@mtiidla, @dhendry, @mostroverkhov, @yshrsmz, @BraisGabin, @cesar1000, @Jawnnypoo, @chanx2, @abersnaze, @davidmoten, @ortex, @marwinxxii, @ekchang, @pyricau, @JakeWharton, @VictorAlbertos
2.1.0
Summary
Version 2.1.0 is the next minor release of the 2.x era and contains the standardization of many experimental API additions from the past half a year since version 2.0.0. Therefore, the following components are now considered stable and will be supported throughout the rest of the life of RxJava 2.x.
Classes, Enums, Annotations
- Annotation:
CheckReturnValue - Subjects:
CompletableSubject,MaybeSubject,SingleSubject - Enum:
TestWaitStrategy
Operators
Flowable:doAfterNext,doFinally,sample(emitLast)Observable:doAfterNext,doFinally,sample(emitLast)Single:doAfterSuccess,doAfterTerminate,doFinallyMaybe:doAfterSuccess,doFinally,flatMapSingleElementCompletable:cache,doFinally,hideTest{Observer, Subscriber}:assertNever,assertTimeout,assertNoTimeout,awaitCount,clearTimeout,isTimeout,withTagRxJavaPlugins:createComputationScheduler,createIoScheduler,createNewThreadScheduler,createSingleScheduler,getOnBeforeBlocking,setOnBeforeBlocking,isFailOnBlockingScheduler,setFailOnBlockingScheduler.- Other:
Scheduler.when,TestSubscriber.requestMore
(For the complete list and details on the promotions, see issue 5243.)
Release 2.1.0 is functionally identical to 2.0.9 except the removal of now unnecessary Flowable.strict() operator. To clarify, just like with previous minor version increments with RxJava, there won't be any further development or updates on the version 2.0.x (patch) level.
Beta promotions
Some of the enhancements of RxJava 2.0.x were added recently which often represent complex additions to RxJava itself (such as the whole ParallelFlowable). We are confident their functionality adds value to the library but not enough time elapsed since their introduction for the community to try it out and provide feedback on them (i.e., naming, encompassed functionality, etc.). To indicate we are willing to support them and eventually standardize them in the next minor release, the following components have been promoted to the status of Beta:
- Classes:
OnErrorNotImplementedException,ProtocolViolationException,UndeliverableException,
ParallelFlowable - Interface:
FlowableSubscriber - Methods
Flowable:parallel,subscribe(FlowableSubscriber)RxJavaPlugins:getOnParallelAssembly,onAssembly(ParallelFlowable),setOnParallelAssembly
Non-functional changes between 2.0.9 and 2.1
- Pull 5306: Change
ObservableSource.defertoObservable.deferinObservable.scan()documentation. - Pull 5309: Fix Javadoc of
Flowable.toObservablereferring toPublisherinstead ofObservable.
Project statistics
- Unique contributors: 41
- Issues closed: 315
- Bugs reported: 43
- by community: 40 (93%)
- Commits: 193
- PRs: 225
- PRs accepted: 198 (88%)
- Community PRs: 76 (38.4% of all accepted)
- Bugs fixed: 58
- by community: 8 (13.9%)
- Documentation enhancements: 46
- by community: 22 (52.2%)
- Cleanup: 40
- by community: 22 (55%)
- Lines
- added: 44,931
- removed: 7,405
Acknowledgements
The project would like to thank the following contributors for their work on various code and documentation improvements (in the order they appear on the commit page):
@vanniktech, @veyndan, @Mauin, @smartbeng, @ImangazalievM, @bloderxd, @mibac138, @ggikko, @mostroverkhov, @sadegh, @nmorioka, @SleimanJneidi, @davidmoten, @hkurokawa, @jbarr21, @alexandre-dubois, @VeskoI, @Stephan202, @PaulWoitaschek, @soulkeykim, @stevepeak, @jschneider, @JakeWharton, @tonycosentini, @hzsweers, @passsy, @sergiomarquesmoura, @ikesyo, @benjchristensen, @zsavely, @DDesideria, @gaemi, @Jawnnypoo, @artem-zinnatullin, @mkobit, @abersnaze, @tbcs, @gengjiawen, @qwert2603, @DmitriyZaitsev
(40 contributors)
The project would also thank its tireless reviewers, @JakeWharton and @vanniktech for all their efforts on verifying and providing feedback on the many PRs from the project lead himself. 👍
1.2.10
2.0.9
API enhancements
- Pull 5302: Add
Single.unsubscribeOn().
Bugfixes
- Pull 5247: Fix
Flowable.toList()onNext/cancelrace. - Pull 5256: Fix
flatMapIterableappearing to be empty when fused. - Pull 5277: Fix
Single.subscribe(BiConsumer)to be consistent withisDisposed. - Pull 5281: Fix
BehaviorProcessor&BehaviorSubjectterminate-subscribe race. - Pull 5287: Fix
Flowable.flatMapMaybe/Flowable.flatMapSinglemaxConcurrencynot requesting more.
Documentation
- Pull 5271: enable link to external JDK, fix
Schedulersstyle. - Pull 5286: Cleanup for text and Javadoc 04/15.
- Commit 7c95808: Fix
DisposableXcopy-paste error in Javadoc. - Pull 5296: Improve
doOnDisposeJavaDoc. - Pull 5297: Fix JavaDoc image for
Single.flatMapObservable(). - Pull 5304: Correct documented return type of
Single.flatMapObservable()'s function argument.
Other
- Pull 5255: Add
NullPointerExceptioncomments andObjectHelpertest code. - Pull 5251: More nullability annotations.
- Pull 5257: Remove
@NonNullannotations fromBiConsumer. - Pull 5268: Remove commented out code from
IoScheduler. - Pull 5301: More detailed no-multi-subscribe error message with the standard consumer types (such as
DisposableObserver).
2.0.8
API enhancements
- Pull 5161: Add
Observable.switchMapSingle() - Pull 5184: Add
offer()method toPublishProcessor&BehaviorProcessor. - Pull 5197: Add
ParallelTransformerinterface. - Pull 5217:
UnicastSubjectfail-fast support. - Pull 5202: Add resilient versions of parallel
map(),filter()anddoOnNext(). - Pull 5226:
UnicastProcessorfail-fast support.
Bugfixes
- Pull 5163:
Single.subscribe()to reportisDisposed()true on success/error. - Pull 5170: Fix
LambdaObservernot cancelling the upstream. - Pull 5182: Fix
replay().refCount()leaking items between connections. - Pull 5188: Fix
flatMapemitting the terminal exception indicator on cancel. - Pull 5207: Prevent tasks to self interrupt on the standard schedulers.
- Pull 5213: Fix
window()with time+size emission problems. - Pull 5240: fix
CallbackCompletableObservercallingonError.
Documentation
- Pull 5189: Declare
concatMapEagerrequires positive prefetch amount. - Pull 5191: Correct java doc for
refCount()return type. - Pull 5208: Fix images of
firstElement,flattenAsX,flatMapIterable,UnicastSubjectandUnicastProcessor. - Pull 5210: Better documentation on the abstract consumer classes (such as
DisposableSubscriber). - Pull 5223: Improve the documentation of
Schedulersutility class. - Pull 5230: Fix wrong comments in
Functions“Function3” -> “BiFunction, Function3”
Other
1.2.9
1.2.8
2.0.7
Reactive-Streams compliance
Related issue 5110, related pull 5112.
RxJava 2's Flowable was designed with Reactive-Streams compliance in mind but didn't follow all rules to the letter. A temporary workaround was the introduction of the strict() operator to enable full compliance. Unfortunately, according to the clarified stance from the specification leads, implementors of Publisher must honor the specification (despite its shortcomings) without excuses or workarounds.
Honoring the specification adds a per-item cost of two atomic increments, manifesting in between the Flowable and an arbitrary Reactive-Streams compliant org.reactivestreams.Subscriber. See Pull 5115 for the benchmark comparison.
Starting from 2.0.7, the Flowable.subscribe(org.reactivestreams.Subscriber) now follows the spec by wrapping via the StrictSubscriber of the strict() operator unless the consuming instance implements a new interface specific to RxJava 2: FlowableSubscriber.
The FlowableSubscriber extends org.reactivestreams.Subscriber but doesn't add any new methods and only overrides four of the textual rules of the specification to enable a relaxed operation within RxJava 2. All internal operators have been converted to use this new interface and thus don't have suffer the per-item overhead required by the specification, including the standard DisposableSubscriber, TestSubscriber and ResourceSubscriber. The lambda-based subscribe() operators were also retrofitted.
If you were implementing a Subscriber (directly or anonymously), you may want to change the interface to FlowableSubscriber. In order to avoid some of the runtime checks when subscribing to Flowable the new subscribe(FlowableSubscriber) has been introduced.
Note that the other reactive base types, Observable, Single, Maybe and Completable are not affected as these were never intended to implement the Reactive-Streams specification (they were only inspired by the spec and are RxJava 2 only to begin with).
API enhancements
- Pull 5117: Add
ParallelFlowable.sequentialDelayError. - Pull 5137: Add
TestSubscriber.withTag. - Pull 5140: Fix timed replay-like components replaying outdated items.
- Pull 5155: Add
TestSubscriber.awaitCount,assertTimeout&assertNoTimeout, improve assertion error message
API deprecations
- Pull 5112:
Flowable.strict()deprecated and will be removed in 2.1.0 - the defaultFlowablebehavior is now strict.
Bugfixes
- Pull 5101: Fix
Maybe.concat()subscribe-after-cancel, verify others. - Pull 5103: Fix
doOnSubscribesignallingUndeliverableExceptioninstead ofonError. - Pull 5106: Fix
window(time, size)not completing windows on timeout. - Pull 5114: Fix
Observable.combineLatestto dispose eagerly. - Pull 5121: Fix
Observable.zipto dispose eagerly. - Pull 5133: Fix
flatMapnot cancelling the upstream eagerly. - Pull 5136: Fix
repeatWhenandretryWhensignatures.
Other
1.2.7
Deprecation of create(OnSubscribe)
The method started out in RxJava 0.x as a simple and direct way for implementing custom operators because 0.x had a much simpler protocol requirements. Over the years, as the Observable protocol evolved and create became a powerful and complicated extension point of RxJava that required users to implement the Observable protocol, including cancellation and backpressure manually.
Unfortunately, guides, blogs, StackOverflow answers and mere typical user behavior still leads to this create method and lots of confusion, unstoppable sequences and MissingBackpressureException. We tried remedying the situation by introducing fromEmitter with limited discoverability success.
Therefore, as of 1.2.7 the create() method is now deprecated (but won't be removed due to binary compatibility requirements). In addition fromEmitter has been deprecate-renamed to create(Action1, BackpressureMode) and the experimental-marked fromEmitter itself will be removed in 1.3.0.
Since the functionality of create() was useful for writing (custom) operators inside and outside of RxJava, the new unsafeCreate(OnSubscribe) method was introduced as the replacement.
The new create() and unsafeCreate() methods will be fast-tracked to become standard in 1.3.0.
API enhancements
- Pull 5086: Deprecate
create(), add alternatives - Pull 5092: Add
Single.merge(Observable<Single<T>>),Observable.flatMapSingle()&Observable.flatMapCompletable. - Pull 5091: Add
subscribeOn(Scheduler, boolean)avoid same-pool deadlock.
API deprecations
- Pull 5086:
- Deprecate
Observable.create(OnSubscribe), - Deprecate
fromEmitterin favor ofObservable.create(Action1, BackpressureMode).
- Deprecate
Bugfixes
- Pull 5091:
create(Action1, BackpressureMode)+subscribeOnavoid same-pool deadlock. - Pull 5123:
throttleFirstdetecting clock-drift backwards to open the gate
Other
- Pull 5125: reduce stack depth with
switchIfEmpty
2.0.6
Undeliverable exceptions
One of the design goals of 2.x was that no errors can be lost. Sometimes, the sequence ends or gets cancelled before the source could emit an onError which has nowhere to go at that point and gets routed to the RxJavaPlugins.onError.
Unlike 1.x, 2.x by default calls Thread.currentThread().getUncaughtExceptionHandler().uncaughtException() which crashes an Android app. Many developers have noticed the increased number of app crashes when porting to 2.x due to this behavior change. Note that this doesn't mean RxJava 2 is unstable but it means you likely had these exceptions all along but they were silently dropped.
Unfortunately, RxJava can't tell which of these out-of-lifecycle, undeliverable exceptions should or shouldn't crash your app. Identifying the source and reason for these exceptions can be tiresome, especially if they originate from a source and get routed to RxJavaPlugins.onError somewhere lower the chain.
Therefore, 2.0.6 introduces specific exception wrappers to help distinguish and track down what was happening the time of the error:
OnErrorNotImplementedException: reintroduced to detect when the user forgot to add error handling tosubscribe().ProtocolViolationException: indicates a bug in an operatorUndeliverableException: wraps the original exception that can't be delivered due to lifecycle restrictions on aSubscriber/Observer. It is automatically applied byRxJavaPlugins.onErrorwith intact stacktrace that may help find which exact operator rerouted the original error.
If an undeliverable exception is an instance/descendant of NullPointerException, IllegalStateException (UndeliverableException and ProtocolViolationException extend this), IllegalArgumentException, CompositeException, MissingBackpressureException or OnErrorNotImplementedException, the UndeliverableException wrapping doesn't happen.
In addition, some 3rd party libraries/code throw when they get interrupted by a cancel/dispose call which leads to an undeliverable exception most of the time. Internal changes in 2.0.6 now consistently cancel or dispose a Subscription/Disposable before cancelling/disposing a task or worker (which causes the interrupt on the target thread).
// in some library
try {
doSomethingBlockingly()
} catch (InterruptedException ex) {
// check if the interrupt is due to cancellation
// if so, no need to signal the InterruptedException
if (!disposable.isDisposed()) {
observer.onError(ex);
}
}If the library/code already did this, the undeliverable InterruptedExceptions should stop now. If this pattern was not employed before, we encourage updating the code/library in question.
API enhancements
- Pull 5036: Reintroduce
OnErrorNotImplementedExceptionfor 0-1 arg subscribe. - Pull 5043: Add parallel hooks to
RxJavaPlugins, add missing params validation - Pull 5080: Wrap undeliverable errors.
- Pull 5093: Add
Single.doAfterTerminate
Bugfixes
- Pull 5064: Fix
replay()cancel/disposeNullPointerException. - Pull 5090: fix
scan(seed, f)to emit accumulated values without delay.
Other
- Pull 5027: Dedicated
Single.zipimplementation, no dispose on all-success. - Pull 5023: Annotate function interfaces.
- Pull 5047: Document and test
ambsubscription ordering. - Pull 5051: More
@Nonnullannotations. - Pull 5054: Add
@Nullableannotation toSimpleQueue. - Pull 5055: More null checks.
- Pull 5049: Use bounded wildcards for
errorHandler. - Pull 5075: Cancel upstream first, dispose worker last.
- Pull 5058: More generics in
RxJavaPlugins. - Pull 5076: Removed documentation leftover of
Completable.subscribe. - Pull 5087: Correct marble diagram dimensions.