Skip to content

Releases: ReactiveX/RxJava

0.20.0-RC6

14 Aug 22:06
Compare
Choose a tag to compare
0.20.0-RC6 Pre-release
Pre-release

Further fixes and enhancements bringing us close to completing 0.20.0 and almost ready for 1.0.

A more major change in this release is the deprecation of Observable.from(T). The full discussion can be seen in #1563.

Artifacts: Maven Central

0.20.0-RC5

13 Aug 17:55
Compare
Choose a tag to compare
0.20.0-RC5 Pre-release
Pre-release

Version 0.20.0-RC5 updates parallel, buffer(size), switchOnNext, repeat, and retry to support "reactive pull" backpressure. It adds a groupBy overload with an element selector, a new compose method as an alternative to lift for custom operators, fixes bugs and other general improvements.

There are still oustanding items being tracked for 0.20 that need to be completed for the final release.

Artifacts: Maven Central

0.20.0-RC4

31 Jul 15:39
Compare
Choose a tag to compare
0.20.0-RC4 Pre-release
Pre-release

Version 0.20.0-RC4 continues bug fixes and completing work related to "reactive pull" backpressure. This release updates amb and concat to connect the backpressure request.

Internal uses of RxRingBuffer migrated to using SpmcArrayQueue which significantly reduces object allocations. See #1526 for details.

The multicast operators were updated to use a Subject factory so that Observable sequences can be reused. See #1515 for details.

  • Pull 1534 Concat Backpressure
  • Pull 1533 Amb + Backpressure
  • Pull 1527 Failing unit test for reduce, showing it does not implement backpressure correctly
  • Pull 1528 Add operators to create Observables from BroadcastReceiver (rebased)
  • Pull 1523 Fix issue #1522: takeLast
  • Pull 1530 Fix the unbounded check for merge
  • Pull 1526 Restore use of SpmcArrayQueue in RxRingBuffer
  • Pull 1468 RxScala: Update CompletenessTest.scala
  • Pull 1515 Support Subject Factory with Multicast
  • Pull 1518 Fix typos in javadoc comments
  • Pull 1521 Fix toIterator Exception Handling
  • Pull 1520 Fix non-deterministic RxRingBuffer test

Artifacts: Maven Central

0.20.0-RC3

25 Jul 19:30
Compare
Choose a tag to compare
0.20.0-RC3 Pre-release
Pre-release

Version 0.20.0-RC3 preview release fixes several bugs related to backpressure and adds retryWhen, repeatWhen for more advanced recursion use cases like retry with exponential backoff.

This version passed the Netflix API production canary process. Please test this against your code to help us find any issues before we release 0.20.0.

Artifacts: Maven Central

0.20.0-RC2

18 Jul 22:25
Compare
Choose a tag to compare
0.20.0-RC2 Pre-release
Pre-release

Version 0.20.0-RC2 preview release adds support for backpressure to the zip operators, fixes bugs and removes the Subscribe.onSetProducer method.

This means signature changes are modified to be:

The new type Producer ->

public interface Producer {
    public void request(long n);
}

New methods added to Subscriber ->

public abstract class Subscriber<T> implements Observer<T>, Subscription {
    public void onStart();
    protected final void request(long n);
    public final void setProducer(Producer producer);
}

Artifacts: Maven Central

0.20.0-RC1

15 Jul 17:28
Compare
Choose a tag to compare
0.20.0-RC1 Pre-release
Pre-release

Version 0.20.0-RC1 is a preview release that adds backpressure support to RxJava as per issue #1000. It has been done in a way that is mostly additive and most existing code will not be affected by these additions. A section below on "Breaking Changes" will discuss use cases that do break and how to deal with them.

This release has been tested successfully in Netflix production canaries, but that does not exercise all use cases or operators, nor does it leverage the newly added backpressure functionality (though the backpressure code paths are used).

Outstanding Work

  • The zip operator has not yet been upgraded to support backpressure. The work is almost done and it will be included in the next release.
  • Not all operators have yet been reviewed for whether they need to be changed in any way.
  • Temporal operators (like buffer, window, sample, etc) need to be modified to disable backpressure upstream (using request(Long.MAX_VALUE)) and a decision made about how downstream backpressure requests will be supported.
  • Ensure all code works on Android. New data structures rely on sun.misc.Unsafe but are conditionally used only when it is available. We need to ensure those conditions are working and the alternative implementations are adequate. The default buffer size of 1024 also needs to be reviewed for whether it is a correct default for all systems, or needs to be modified by environment (such as smaller for Android).
  • Ensure use cases needing backpressure all work.

Signature Changes

A new type Producer has been added:

public interface Producer {
    public void request(long n);
}

The Subscriber type now has these methods added:

public abstract class Subscriber<T> implements Observer<T>, Subscription {
    public void onStart();
    public final void request(long n);
    public final void setProducer(Producer producer);
    protected Producer onSetProducer(Producer producer);
}

Examples

This trivial example shows requesting values one at a time:

Observable.from(1, 2, 3, 4).subscribe(new Subscriber<Integer>() {

    @Override
    public void onStart() {
        request(1);
    }

    @Override
    public void onCompleted() {
    }

    @Override
    public void onError(Throwable e) {
    }

    @Override
    public void onNext(Integer t) {
        request(1);
    }

});

The OnSubscribeFromIterable operator shows how an Iterable is consumed with backpressure.

Some hi-lights (modified for simplicity rather than performance and completeness):

public final class OnSubscribeFromIterable<T> implements OnSubscribe<T> {

    @Override
    public void call(final Subscriber<? super T> o) {
        final Iterator<? extends T> it = is.iterator();
        // instead of emitting directly to the Subscriber, it emits a Producer
        o.setProducer(new IterableProducer<T>(o, it));
    }

    private static final class IterableProducer<T> implements Producer {

        public void request(long n) {
            int _c = requested.getAndAdd(n);
            if (_c == 0) {
                while (it.hasNext()) {
                    if (o.isUnsubscribed()) {
                        return;
                    }
                    T t = it.next();
                    o.onNext(t);
                    if (requested.decrementAndGet() == 0) {
                        // we're done emitting the number requested so return
                        return;
                    }
                }

                o.onCompleted();
            }

        }
    }
}

The observeOn operator is a sterotypical example of queuing on one side of a thread and draining on the other, now with backpressure.

private static final class ObserveOnSubscriber<T> extends Subscriber<T> {
        @Override
        public void onStart() {
            // signal that this is an async operator capable of receiving this many
            request(RxRingBuffer.SIZE);
        }

        @Override
        public void onNext(final T t) {
            try {
                // enqueue
                queue.onNext(t);
            } catch (MissingBackpressureException e) {
                // fail if the upstream has not obeyed our backpressure requests
                onError(e);
                return;
            }
            // attempt to schedule draining if needed
            schedule();
        }

        // the scheduling polling will then drain the queue and invoke `request(n)` to request more after draining
}

Breaking Changes

The use of Producer has been added in such a way that it is optional and additive, but some operators that used to have unbounded queues are now bounded. This means that if a source Observable emits faster than the Observer can consume them, a MissingBackpressureException can be emitted via onError.

This semantic change can break existing code.

There are two ways of resolving this:

  1. Modify the source Observable to use Producer and support backpressure.
  2. Use newly added operators such as onBackpressureBuffer or onBackpressureDrop to choose a strategy for the source Observable of how to behave when it emits more data than the consuming Observer is capable of handling. Use of onBackpressureBuffer effectively returns it to having an unbounded buffer and behaving like version 0.19 or earlier.

Example:

sourceObservable.onBackpressureBuffer().subscribe(slowConsumer);

Relation to Reactive Streams

Contributors to RxJava are involved in defining the Reactive Streams spec. RxJava 1.0 is trying to comply with the semantic rules but is not attempting to comply with the type signatures. It will however have a separate module that acts as a bridge between the RxJava Observable and the Reactive Stream types.

The reasons for this are:

  • Rx has Observer.onCompleted whereas Reactive Streams has onComplete. This is a massive breaking change to remove a "d".
  • The RxJava Subscription is used also a "Closeable"/"Disposable" and it does not work well to make it now also be used for request(n), hence the separate type Producer in RxJava. It was attempted to reuse rx.Subscription but it couldn't be done without massive breaking changes.
  • Reactive Streams uses onSubscribe(Subscription s) whereas RxJava injects the Subscription as the Subscriber. Again, this change could not be done without major breaking changes.
  • RxJava 1.0 needs to be backwards compatible with the major Rx contracts established during the 0.x roadmap.
  • Reactive Streams is not yet 1.0 and despite significant progress, it is a moving target.

Considering these things, the major semantics of request(long n) for backpressure are compatible and this will allow interop with a bridge between the interfaces. As the Reactive Streams spec matures, RxJava 2.0 may choose to fully adopt the types in the future while RxJava 1.x retains the current signatures.

How to Help

First, please test this release against your existing code to help us determine if we have broken anything.

Second, try to solve backpressure use cases and provide feedback on what works and what doesn't work.

Thank you!

Artifacts: Maven Central

0.19.6

09 Jul 05:11
Compare
Choose a tag to compare

Inclusion of rxjava-scalaz in release.

Artifacts: Maven Central

0.19.4

07 Jul 21:56
Compare
Choose a tag to compare
  • Pull 1401 OnError while emitting onNext value: object.toString
  • Pull 1409 Avoiding OperatorObserveOn from calling subscriber.onNext(..) after unsubscribe
  • Pull 1406 Kotlin M8
  • Pull 1400 Internal Data Structures
  • Pull 1399 Update Perf Tests
  • Pull 1396 RxScala: Fix the compiler warnings
  • Pull 1397 Adding the hooks unsafeSubscribe

Artifacts: Maven Central

0.19.2

26 Jun 16:24
Compare
Choose a tag to compare
  • Pull 1388 CompositeException stops mutating nested Exceptions
  • Pull 1387 Upgrade to JMH 0.9
  • Pull 1297 [RxScala] rxjava-scalaz: providing some type class instances
  • Pull 1332 IOSSchedulers for RoboVM
  • Pull 1380 Variety of Fixes
  • Pull 1379 Parallel Operator Rewrite
  • Pull 1378 BugFix: Pivot Concurrency
  • Pull 1376 Revision of JMH Tests
  • Pull 1375 RxScala: Add idiomatic toXXX methods
  • Pull 1367 Fix the bug that 'flatMap' swallows OnErrorNotImplementedException
  • Pull 1374 Fix head/tail false sharing issues
  • Pull 1369 DebugHook got miswired before
  • Pull 1361 Fix a race condition if queued actions have been handled already
  • Pull 1336 RxScala: Add the rest missing methods to BlockingObservable
  • Pull 1362 RxScala: Fix #1340 and #1343
  • Pull 1359 Fixed padding of the integer and node classes

Artifacts: Maven Central

0.19.1

12 Jun 18:13
Compare
Choose a tag to compare
  • Pull 1357 MergeWith, ConcatWith, AmbWith
  • Pull 1345 RxScala: Simplify doOnCompleted/Terminate, finallyDo callback usage
  • Pull 1337 Make Future receive NoSuchElementException when the BlockingObservable is empty
  • Pull 1335 RxAndroid: Bump build tools to 19.1 and android plugin to 0.11
  • Pull 1327 Join patterns extension for 4..9 and N arity joins.
  • Pull 1321 RxAndroid: Ensuring Runnables posted with delay to a Handler are removed when unsubcribed
  • Pull 1347 Allow use of the returned subscription to cancel periodic scheduling
  • Pull 1355 Don't add the subscriber to the manager if it unsubscribed during the onStart call
  • Pull 1350 Baseline Performance Tests
  • Pull 1316 RxScala: Add the rest operators
  • Pull 1324 TrampolineScheduler & Unsubscribe
  • Pull 1311 Tiny integration test change

Artifacts: Maven Central