Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should Observable.range and Observable.from be in BlockingObservable? #291

Closed
Treora opened this issue Jun 6, 2013 · 3 comments
Closed

Comments

@Treora
Copy link
Contributor

Treora commented Jun 6, 2013

I imagine Observable.range and Observable.from are so primitive that they are expected to be in the normal Observable, but they are really blocking on subscribe which can be unexpected. In fact it took me a while wondering why my groupBy unit test (4f68c5a) did not work at first (using range instead of a custom CounterSource), before I figured out that it is simply impossible to unsubscribe from range.
According to the plan of moving blocking operators to BlockingObservable (#272), it seems the correct place for these methods (and maybe others?) too, although strictly speaking they might not be operators but generators.

I see two possibilities:
Moving from and range to BlockingObservable:
BlockingObservable<T> source = BlockingObservable.from(items);
or keeping them in Observable but changing their return type, to give the hint to the user:
BlockingObservable<T> source = Observable.from(items);

@headinthebox
Copy link
Contributor

That would be wrong.
Range is blocking because the default scheduler, as is return, and other operators.

Moreover encoding this in the return type is totally useless since after you compose it with another operator that knowledge is lost. Encoding properties of an observable in the return type just does not work.

My guess us that it is probably ok to always use newthreadscheduler as the default, for .net we had long discussions on what to use as the defaults but never measured.

Sent from my iPhone

On Jun 6, 2013, at 3:11 AM, Gerben notifications@github.com wrote:

I imagine Observable.range and Observable.from are so primitive that they are expected to be in the normal Observable, but they are really blocking on subscribe which can be unexpected. In fact it took me a while wondering why my groupBy unit test (4f68c5a) did not work at first (using range instead of a custom CounterSource), before I figured out that it is simply impossible to unsubscribe from range.
According to the plan of moving blocking operators to BlockingObservable (#272), it seems the correct place for these methods (and maybe others?) too, although strictly speaking they might not be operators but generators.

I see two possibilities:
Moving from and range to BlockingObservable:
BlockingObservable source = BlockingObservable.from(items);
or keeping them in Observable but changing their return type, to give the hint to the user:
BlockingObservable source = Observable.from(items);


Reply to this email directly or view it on GitHub.

@Treora
Copy link
Contributor Author

Treora commented Jun 6, 2013

Range is blocking because the default scheduler [...]

It would of course be the nicest solution if from and range would not block in general, but my first guess was that this blocking behaviour was intended. I now see Rx.Net solves Range by scheduling the loop function, which would probably be nice to do in RxJava to.

Currently from works like this in RxJava:

public Subscription call(Observer<T> observer) {
    for (T item : iterable) {
        observer.onNext(item);
    }
    observer.onCompleted();

    return Subscriptions.empty();
}

@benjchristensen
Copy link
Member

We have chosen to not add concurrency (and that matches Rx Design Guideline 6.12. Avoid introducing concurrency) when Observables are created. It is up to the developer to choose to do so.

This can be done within the Observable itself, or using subscribeOn and observeOn.

Beyond this I'm interested in exploring lazy iterable implementations - a feature that is far easier in C# which supports async/await as part of the language. This is of particular interest to me on range and from for the reasons you bring up.

It is not correct though to move from and range to BlockingObservable as that represents the operators on the Observable being blocking instead of non-blocking. Non-blocking operators can be applied to a blocking or non-blocking Observable - it is the source Observable that chooses, and there are times when it makes perfect sense to be blocking, such as when pulling data from an in-memory cache and immediately emitting it without the overhead of thread scheduling.

jihoonson pushed a commit to jihoonson/RxJava that referenced this issue Mar 6, 2020
…r configurations and overriding of Spring beans.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants