# RxJava design retrospect

DevFeed: [RxJava design retrospect](<https://devfeed.tech/articles/rxjava-design-retrospect-24798.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2016/03/rxjava-design-retrospect.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2016-03-05T19:32:00Z

Content type: opinion

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [reactive](<https://devfeed.tech/topics/reactive.md>), [interfaces](<https://devfeed.tech/topics/interfaces.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [blog-post](<https://devfeed.tech/tags/blog-post.md>), [code](<https://devfeed.tech/tags/code.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [interfaces](<https://devfeed.tech/tags/interfaces.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>)

## AI overview

This retrospective examines design and implementation decisions in RxJava, focusing on synchronous cancellation. It explains how RxJava's early observable and observer interfaces could prevent timely disposal of a running sequence, compares this with Rx.NET's scheduling approach, and discusses performance differences in a range operator benchmark.

## Source excerpt

Intoduction RxJava is now out more than 3 years and lived through several significant version changes. In this blog post, I'll point out design and implementation decisions that I personally think wasn't such a good idea. Don't get me wrong, it doesn't mean that RxJava is bad or I knew all along how to do it "properly". It was a learning process for all of us involved, but the question is, can we learn from those mistakes and do it better in the next major version? Synchronous unsubscription In the early days, RxJava mirrored the architecture of Rx.NET which consisted of two important interfaces, IObservable and IObserver, derived through dualizing the IEnumerable and IEnumerator. (This was also true for my own library, Reactive4Java). If we look at IObservable, we find the subscribe() method that returns an IDisposable. This returned object allows one to dispose or cancel a running sequence. However, it has a critical problem I demonstrate with a minimalistic reactive program: interface IDisposable { void dispose(); } interface IObserver<T> { void onNext(T t); } interface IObservable<T> { IDisposable subscribe(IObserver<T> observer); } IObservable<Integer> source = o -> { for (int i = 0; i < Integer.MAX_VALUE; i++) { o.onNext(i); } return () -> { }; }; IDisposable d = o.subscribe(System.out::println); d.dispose(); If we run this code, it starts to print a lot of numbers to the console, despite we called dispose on the returned object by the subscribe method. What's wrong? The problem is that the source observable can only return its IDisposable object only after the for-loop finishes, but then it has nothing to do. The whole setup is synchronous and thus this structure can't be reasonably cancelled. Although Rx is good at async processing, many steps in a typical pipeline is synchronous and is affected by this synchronous cancellation requirement. Since Rx.NET is at least 3 years older than RxJava, how could this shortcoming still be in today's Rx.NET? The example