Skip to content

Latest commit

 

History

History
407 lines (291 loc) · 35.7 KB

CHANGES.md

File metadata and controls

407 lines (291 loc) · 35.7 KB

RxJava Releases

Version 1.x can be found at https://github.com/ReactiveX/RxJava/blob/1.x/CHANGES.md

Version 2.0.7 - March 7, 2017 (Maven)

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 default Flowable behavior is now strict.

Bugfixes

  • Pull 5101: Fix Maybe.concat() subscribe-after-cancel, verify others.
  • Pull 5103: Fix doOnSubscribe signalling UndeliverableException instead of onError.
  • Pull 5106: Fix window(time, size) not completing windows on timeout.
  • Pull 5114: Fix Observable.combineLatest to dispose eagerly.
  • Pull 5121: Fix Observable.zip to dispose eagerly.
  • Pull 5133: Fix flatMap not cancelling the upstream eagerly.
  • Pull 5136: Fix repeatWhen and retryWhen signatures.

Other

  • Pull 5102: Added missing @NonNull attribute to Function7.
  • Pull 5112: Flowable as a Publisher to be fully RS compliant.
  • Pull 5127: Update javadoc of flatMap() overloads.
  • Pull 5153: Java 9 compatibility fixes
  • Pull 5156: Add @NonNull to the methods of Emitter

Version 2.0.6 - February 15, 2017 (Maven)

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 to subscribe().
  • ProtocolViolationException: indicates a bug in an operator
  • UndeliverableException: wraps the original exception that can't be delivered due to lifecycle restrictions on a Subscriber/Observer. It is automatically applied by RxJavaPlugins.onError with 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 OnErrorNotImplementedException for 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/dispose NullPointerException.
  • Pull 5090: fix scan(seed, f) to emit accumulated values without delay.

Other

  • Pull 5027: Dedicated Single.zip implementation, no dispose on all-success.
  • Pull 5023: Annotate function interfaces.
  • Pull 5047: Document and test amb subscription ordering.
  • Pull 5051: More @Nonnull annotations.
  • Pull 5054: Add @Nullable annotation to SimpleQueue.
  • 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.

Version 2.0.5 - January 27, 2017 (Maven)

The most notable enhancement of this version is the inclusion of the ParallelFlowable API that allows parallel execution of a few select operators such as map, filter, concatMap, flatMap, collect, reduce and so on. Note that is a parallel mode for Flowable (a sub-domain specific language) instead of a new reactive base type.

Consequently, several typical operators such as take, skip and many others are not available and there is no ParallelObservable because backpressure is essential in not flooding the internal queues of the parallel operators as by expectation, we want to go parallel because the processing of the data is slow on one thread.

The easiest way of entering the parallel world is by using Flowable.parallel:

ParallelFlowable<Integer> source = Flowable.range(1, 1000).parallel();

By default, the parallelism level is set to the number of available CPUs (Runtime.getRuntime().availableProcessors()) and the prefetch amount from the sequential source is set to Flowable.bufferSize() (128). Both can be specified via overloads of parallel().

ParallelFlowable follows the same principles of parametric asynchrony as Flowable does, therefore, parallel() on itself doesn't introduce the asynchronous consumption of the sequential source but only prepares the parallel flow; the asynchrony is defined via the runOn(Scheduler) operator.

ParallelFlowable<Integer> psource = source.runOn(Schedulers.io());

The parallelism level (ParallelFlowable.parallelism()) doesn't have to match the parallelism level of the Scheduler. The runOn operator will use as many Scheduler.Worker instances as defined by the parallelized source. This allows ParallelFlowable to work for CPU intensive tasks via Schedulers.computation(), blocking/IO bound tasks through Schedulers.io() and unit testing via TestScheduler. You can specify the prefetch amount on runOn as well.

Once the necessary parallel operations have been applied, you can return to the sequential Flowable via the ParallelFlowable.sequential() operator.

Flowable<Integer> result = psource.filter(v -> v % 3 == 0).map(v -> v * v).sequential();

Note that sequential doesn't guarantee any ordering between values flowing through the parallel operators.

For further details, please visit the wiki page about Parallel flows. (New content will be added there as time permits.)

API enhancements

  • Pull 4955: add sample() overload that can emit the very last buffered item.
  • Pull 4966: add strict() operator for strong Reactive-Streams conformance
  • Pull 4967: add subjects for Single, Maybe and Completable
  • Pull 4972: Improve compose() generics
  • Pull 4973: Add Completable.hide()
  • Pull 4974: add Flowable.parallel() and parallel operators
  • Pull 5002: Add scheduler creation factories

Bugfixes

  • Pull 4957: fix LambdaObserver calling dispose when terminating
  • Pull 4962: fix takeUntil() other triggering twice
  • Pull 4970: fix withLatestFrom null checks, lifecycle
  • Pull 4982: fix Observable.concatMapEager bad logic for immediate scalars.
  • Pull 4984: fix cross-boundary invalid fusion with observeOn, flatMap & zip
  • Pull 4987: Make Observable.combineLatest consistent with Flowable, fix early termination cancelling the other sources and document empty source case
  • Pull 4992: A.flatMapB to eagerly check for cancellations before subscribing
  • Pull 5005: ExecutorScheduler.scheduleDirect to report isDisposed on task completion

Other

  • Pull 4971: Add @CheckReturnValue to create() methods of Subjects + Processors
  • Pull 4980: Update Copyright to 'RxJava Contributors'
  • Pull 4990: Update marble diagrams for sample() overloads, Maybe and Maybe.switchIfEmpty()
  • Pull 5015: Fix Reactive-Streams dependency to be compile in the library's POM
  • Pull 5020: option to fail for using blockingX on the computation/single scheduler

Version 2.0.4 - January 4, 2017 (Maven)

API enhancements

Bugfixes

  • Pull 4927: fix timer() IllegalStateException due to bad resource management
  • Pull 4932: Add safeguards to generate()
  • Pull 4943: Fix publish(Function) not replenishing its internal queue
  • Pull 4945: Fix timeout with fallback not cancelling/disposing the main source connection.

Version 2.0.3 - December 18, 2016 (Maven)

Bugfixes

  • Pull 4899: FlowableScanSeed - prevent post-terminal events
  • Pull 4901: FlowableScan - prevent multiple terminal emissions
  • Pull 4903: doAfterNext - prevent post-terminal emission
  • Pull 4904: Observable.scan no seed fix post-terminal behaviour
  • Pull 4911: fix & update Observable.repeatWhen and retryWhen
  • Pull 4924: flatMapCompletable change Completable to CompletableSource

Other

  • Pull 4907: Use t instead of value to allow for IDE naming

Version 2.0.2 - December 2, 2016 (Maven)

API enhancements

  • Pull 4858: add Maybe.flatMapSingleElement returning Maybe
  • Pull 4881: Add @CheckReturnValue annotation to aid static verification tools

Performance enhancements

  • Pull 4885: Dedicated reduce() op implementations

Bugfixes

  • Pull 4873: TestObserver shouldn't clear the upstream disposable on terminated
  • Pull 4877: Apply missing RxJavaPlugins.onAssembly on ops
  • Commit bf0c: Fix firstOrError converted back to Observable/Flowable not reporting NoSuchElementException.

Version 2.0.1 - November 12, 2016 (Maven)

API enhancements

  • Pull 4827: Porting the Scheduler.when operator from 1.x to 2.x
  • Pull 4831: add Flowable.doFinally(Action) for handling post-terminal or cancel cleanup.
  • Pull 4832: add doFinally to the rest of the reactive base classes
  • Pull 4833: add Flowable.doAfterNext operator
  • Pull 4835: add Observable.doAfterNext and {Single|Maybe}.doAfterSuccess.
  • Pull 4838: add fluent TestSubscriber.requestMore

Documentation fixes/enhancements

  • Pull 4793: Fix javadoc mentioning IllegalArgumentException instead of NullPointerException for calling with null parameter(s).
  • Pull 4798: Fix Observable.toFlowable documentation
  • Pull 4803: Fix ObservableEmitter mentioning FlowableEmitter.
  • Pull 4810: Fix Completable.retryWhen terminology about signal emission.
  • Pull 4815: Fix typo in javadoc of Maybe.toSingle
  • Pull 4839: fix wording of some operators, remove @throws implications

Bugfixes

  • Pull 4783: Fix Observable.repeatWhen & retryWhen not disposing the inner.
  • Pull 4819: Fix Observable.repeatWhen not reacting to upstream onError properly.

Version 2.0.0 - October 29, 2016 (Maven)

This is it, general availability of RxJava 2! Rewritten from scratch to offer better performance, lower overhead, more features, a modern underlying technology and interoperation with the Reactive-Streams ecosystem. Big thanks goes to the several dozen people who gave feedback, fixes, enhancements and reviewed pull requests in the past, very intensive, 4 months.

Users are encouraged to read the wiki articles What's different in 2.0 and Writing operators for 2.0 to get a overview about changes and differences between working with RxJava 1 and 2. If you find something missing or under-explained, don't worry and open an issue about it!

Some other common libraries such as RxAndroid and Retrofit 2 Adapter were already following the 2.x development and you can expect them to release versions supporting the 2.0.0 GA shortly. In addition, there is an ongoing effort to port companion libraries of RxJava itself to support the 2.x line. For now, several ported features are available as part of the RxJava2Extensions project. RxJava 1 and 2 can live side by side in the same project and the RxJava2Interop library allows dataflow conversions between the two versions.

The sections below contain the changes since 2.0.0-RC5 beyond the general quality and test coverage improvements of the codebase.

API enhancements

  • Pull 4760: Add Single.fromObservable(ObservableSource)
  • Pull 4767: Rename BackpressureStrategy.NONE to MISSING

Documentation enhancements

  • Pull 4744: Fixed Javadoc for Disposables.fromFuture
  • Pull 4749: New 2.x marble diagrams
  • Pull 4752: Add more new marble diagrams & update old ones

Performance enhancements

  • Pull 4742:
    • cleanup Flowable.publish() and enable operator fusion on its input
    • compact Flowable.blockingSubscribe(), Observable.blockingSubscribe() and Flowable.subscribeOn()
  • Pull 4761:
    • Unify MapNotification, Materialize, OnErrorReturn last element backpressure under the same helper class.
    • Reuse parts of FlowableSequenceEqual in FlowableSequenceEqualSingle.
  • Pull 4766: Flowable.scan(T, BiFunction) now emits the initial value only when the upstream signals an event.

Bugfixes

  • Pull 4742:
    • Fix Flowable.materialize() terminal signal emission in face of backpressure.
    • Fix Flowable.onErrorReturn() terminal signal emission in face of backpressure.
    • fix Flowable.flatMapSingle() and Flowable.flatMapMaybe() termination detection
  • Pull 4747: distinctUntilChanged to store the selected key instead of the value
  • Pull 4751: fix Flowable.concatMapEager hang due to bad request management.
  • Pull 4761: Fix cancellation bugs in Flowable operators.
  • Pull 4763: rewrite of takeUntil to avoid onSubscribe() races.
  • Pull 4766:
    • Fix Flowable.skipUntil lifecycle and concurrency properties.
    • Fix Flowable.concatMapEager error management.
  • Pull 4770: allow subscribeOn to work with blocking create.

Version 2.0.0-RC5 - October 21, 2016 (Maven)

This release contains API fixes, further cleanups to code and javadoc, better test coverage and bugfixes. Thanks to the respective contributors and @JakeWharton for the reviews.

API enhancements

  • Pull 4685: Test static from methods and add Maybe.fromSingle & fromCompletable
  • Pull 4687: Add Observable.rangeLong & Flowable.rangeLong.
  • Pull 4690: BaseTestConsumer add assertValueAt(index, Predicate<T>).
  • Pull 4711: Decouple stream operators from Function interface (FlowableOperator and co).
  • Pull 4712: make Observable.sequenceEqual return Single
  • Pull 4714: have Flowable.toList(Callable) return Single
  • Pull 4720: remove variance from the input source of retryWhen
  • Pull 4723: remove flatMapIterable(Function, int) overload and have flatMapIterable(Function) use the flatten operator.
  • Pull 4729: Merge FlowableEmitter.BackpressureMode into BackpressureStrategy
  • Pull 4710: Remove checked exceptions from transformer interfaces.

Performance enhancements

  • Pull 4723: enable fusion on Observable.observeOn

Bugfixes

  • Pull 4681: Fix Flowable + Single elementAt and elementAtOrError operators on empty sources.
  • Pull 4686: Fix flatMapX over-cancellation in case of an inner error.
  • Pull 4689: Fix doOnEvent NPE on dispose()
  • Pull 4695: CompositeException fix order of exceptions
  • Pull 4696: Fix inner Throwable order for CompletablePeek
  • Pull 4705: fix Observable.flatMap's dispose behavior and error accumulation
  • Pull 4707: Fix Flowable.elementAt on empty sources.
  • Pull 4708: fix Observable.publish(Function) latecommer behavior
  • Pull 4712: fix Observable.combineLatest error management, fix Observable.flatMap maxConcurrency behavior with scalars, use of unbounded queue, fix Observable.timeInterval not saving the Disposable
  • Pull 4723: fix fusion of Observable.just, fix Observable.replay() potential emission before onSubscribe call
  • Pull 4731: Delegate null Collections down to onError in toList
  • Pull 4736: fix onBackpressureBuffer(long, Action, BufferOverflowStrategy) return type, fix concatMapDelayError wrong barrier mode selected.
  • Pull 4738: Fix Flowable.flatMap error, cancellation and resource management.

Removals

  • Pull 4689: Remove Maybe.toCompletable, use Maybe.ignoreElement.
  • Pull 4708: remove bufferSize overloads of Observable.publish as there is no need to buffer anything for an Observable
  • Pull 4723: remove flatMapIterable(Function, int) overload

Other

  • Pull 4682: Update Mockito to 2.1.0
  • Pull 4699: Clean up null usages by using ObjectHelper.requireNonNull.

Version 2.0.0-RC4 - October 7, 2016 (Maven)

This release contains new operators, further cleanups, better test coverage and bugfixes. Thanks to the respective contributors and @JakeWharton for the reviews.

API enhancements

  • Pull 4589: Add singleOrError, firstOrError, lastOrError & elementAtOrError to Observable and Flowable
  • Pull 4616: Add Completable.andThen(MaybeSource)
  • Pull 4614: Add Maybe.flatMapSingle
  • Pull 4617: Add Single.flatMapMaybe
  • Pull 4585: Evaluate Schedulers initialization via Callable
  • Pull 4607: TestSubscriber & TestObserver add assertValue(Predicate).
  • Pull 4627: Use predicates in BaseTestConsumer.assertError(Class/Throwable) to remove duplicate code, tests tweaks to remove few IDE warnings
  • Pull 4629: Add Completable.fromRunnable()
  • Pull 4631: TestConsumer don't wrap with CompositeException when there is only one error
  • Pull 4604: add flattenAs{Observable,Flowable} to Single and Maybe
  • Pull 4658: Observable.compose to use ObservableTransformer.
  • Pull 4667: Add flatMap{Completable, Maybe, Single} operators to Flowable and Observable.
  • Pull 4672: Remove Function from transformer interfaces to allow a single obj.
  • Maybe.ignoreElement to return Completable.

Performance enhancements

  • Pull 4612: Improve performance of Observable.flatMapIterable
  • Pull 4622: Enable operator fusion in onBackpressureBuffer

Bugfixes

  • Pull 4590: Report errors from onError to Plugin when done.
  • Pull 4592: UnicastSubject fix onTerminate
  • Pull 4593: Enhance NPE messages
  • Pull 4603: RxJavaPlugins - Don't pass null throwable down to Error Handler
  • Pull 4619: Make CompositeExcepetion thread-safe like 1.x and also fix some issues.
  • Pull 4645: Signal NPE ObservableAmb FlowableAmb
  • Pull 4651: Switch Maybe and Single to use their Transformers in compose().
  • Pull 4654: Upcast ConcurrentHashMap to Map to avoid compatibility issue.

Removals

  • Pull 4595: Remove takeFirst(predicate) from Observable & Flowable

Other

  • Pull 4647: Merge AmbArray and AmbIterable into Amb for Single, Maybe and Completable types.

Version 2.0.0-RC3 - September 23, 2016 (Maven)

This Release Candidate features mostly internal cleanups of code and Javadoc, Reactive-Streams Test Compatibility Kit implementations (and thus verification) of our Flowable implementation and additional unit-test coverage. Big tanks to @vanniktech for the many contributions and @JakeWharton for the continued reviews.

Other notable changes:

  • The new Maybe type of RC2 now features all relevant operators.
  • Many Observable and Flowable operators now return Single or Maybe.
  • Pull 4525 : Fixed generics of combineLatest and zip because Function<? super T[], R> doesn't work.
  • Pull 4522 : Fixed delay operator to call onError on the provided scheduler
  • Pull 4490 : rename isCancelled to isDisposed inside the varios emitters of create()
  • Pull 4504 : add default XObserver implementation to Single, Maybe and Completable
  • Pull 4518 : add ResourceXObserver implementation to Single, Maybe and Completable
  • Pull 4536 : fix timeout operators not properly cancelling/disposing the upstream.
  • Pull 4583 : Flowable.create()'s FlowableEmitter didn't handle nulls properly.
  • Pull 4586 : Add error assertion with predicate to TestSubscriber and TestObserver.

In addition, the wiki page What's different in 2.0 has been extended with more information.

Version 2.0.0-RC2 - September 5, 2016 (Maven)

This Release Candidate features a large amount of internal fixes, cleanups and enhancements. Please refer to the closed PRs for its milestone. This includes the bugfix for the Single.subscribeOn failing with Disposable already set! error printed to the console (Issue 4448, Pull 4450).

The library now has a new base reactive type: Maybe which is essentially a Single and Completable combined. You can have exactly 1 onSuccess, 1 onError or 1 onComplete signals with it. Note however that it doesn't have all the operators possible for this type of source but you can convert it back and forth to the other base reactive types (i.e., Flowable, Single, Completable and Observable). Unlike Project Reactor's Mono type, this doesn't implement the Reactive-Streams Publisher (but is designed along the idea) and doesn't have backpressure (as there is no chance of buffer-bloat like with unknown length Flowables and Observables).

Version 2.0.0-RC1 - August 25, 2016 (Maven)

RxJava 2.0 has been rewritten from scratch to be more performant, lower overhead (memory and cpu) and to natively implement the Reactive-Streams specification in its new Flowable type. The library still supports Java 6+ and is considered a 4th generation reactive library.

There have been hundreds of PRs and large amounts of changes compared to the 1.x version. The two are binary-incompatible but their distinct maven coordinates (io.reactivex.rxjava2:rxjava:2.0.0-RC1) allow them to co-exist. You can use the rxjava2-interop library to convert between 1.x and 2.x types.

Please refer to the wiki page about the differences between the two major versions.

Converting the companion libraries is an ongoing effort. For now, see the rxjava2-extensions project that contains the port of the RxJavaMath features. Note that most companion libraries of RxJava are currently not set up properly for release (the signing keys are missing from the CI release process) and is unknown if and when they will have their own 2.x release branch.

I'd like to thank for the contributions of the following community members (in LIFO commit-merge order):

@davidmoten, @JakeWharton, @vanniktech, @dimitar-asenov, @artem-zinnatullin, @bobvanderlinden, @DmitriyZaitsev, @zsxwing, @bcorne, @stevegury, @benjchristensen, @stealthcode, @adam-arold and @abersnaze.

A special thanks goes out to @smaldini, Project-Reactor lead at Pivotal. Our ongoing cooperation lead to the massive improvement of the RxJava 2.x architecture (originally designed in August 2015) by learning from and building upon the results of the Reactive-Streams-Commons research project.