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

Implemented: ForEach #131

Closed
wants to merge 5 commits into from
Closed

Implemented: ForEach #131

wants to merge 5 commits into from

Conversation

dcapwell
Copy link

@dcapwell dcapwell commented Feb 8, 2013

implement #45.

@benjchristensen
Copy link
Member

Hi @dcapwell, thanks for contributing!

The code looks great, only thing I see missing is support for dynamic languages which requires "Object" overloads of any method with Func* or Action* arguments so closures from Groovy/Clojure/Scala/JRuby/etc can be passed in.

For example:

-> typed: https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/Observable.java#L2212
-> non-typed: https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/Observable.java#L2269

You'll see how it takes the 'Object' and derives a FuncN from it and then invokes the appropriate typed method:

public static <T> Observable<List<T>> toSortedList(Observable<T> sequence, final Object sortFunction) {
        @SuppressWarnings("rawtypes")
        final FuncN _f = Functions.from(sortFunction);
        return create(OperationToObservableSortedList.toSortedList(sequence, new Func2<T, T, Integer>() {

            @Override
            public Integer call(T t1, T t2) {
                return (Integer) _f.call(t1, t2);
            }

        }));
    }

If you can confirm that the methods work from at least one of the dynamic languages by adding a unit test for each of the overloads I would appreciate it.

Groovy is the primary one we use thus far (most similar to Java): https://github.com/Netflix/RxJava/blob/master/language-adaptors/rxjava-groovy/src/test/groovy/rx/lang/groovy/ObservableTests.groovy

Thank you again!

dcapwell added 2 commits February 8, 2013 00:33
@dcapwell
Copy link
Author

dcapwell commented Feb 9, 2013

Is there a better way to handle the errors than just skipping calling the user code?

@benjchristensen
Copy link
Member

Can you point me to a part of the code where that question refers to?

If an error occurs (either in the operator itself or the Func passed in) the appropriate thing (and only option really) is to call onError.

@dcapwell
Copy link
Author

dcapwell commented Feb 9, 2013

https://github.com/dcapwell/RxJava/commit/30f855b021a8feb673a34cda2c5022c8f74e9541#L1R115

If onNext throws an exception, then onError is called and all calls to onNext, onError, or onComplete get ignored after.

@benjchristensen
Copy link
Member

Yes that's the correct behavior to call onError if an exception is thrown.

If the code is working as designed (I think it is!) then it will also automatically unsubscribe to the parent Observable.

You can see how here: https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/util/AtomicObserver.java#L60

The Observer is wrapped when the Observable is subscribed to. You can see that here: https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/Observable.java#L132

That ensures the onError/onCompleted only get called once and onNext will be ignored and takes care of automatically unsubscribing in the event it doesn't get done correctly elsewhere.

@dcapwell
Copy link
Author

dcapwell commented Feb 9, 2013

Would it be fine to make forEach not support static operators? If so then i can have it unsubscribe. Basically just replicate this code:

AtomicObservableSubscription subscription = new AtomicObservableSubscription();
return subscription.wrap(onSubscribe.call(new AtomicObserver<T>(subscription, observer)));

and have onComplete and onError unsubscribe like AtomicObserver does.

@benjchristensen
Copy link
Member

Since forEach is basically just a blocking version of subscribe, I'd like to propose a different approach that uses subscribe but blocks until onError or onCompleted are received.

There is very little new code for this (mostly just overloads) and this blocks if the Observable is asynchronous.

Pull Request: #147

The interesting part of the code is here: https://github.com/Netflix/RxJava/pull/147/files#L1R368

It uses a CountDownLatch to block until onError or onCompleted are received.

@benjchristensen
Copy link
Member

Re-reading the specs ... we should actually eliminate the onError/onCompleted overloads as they are not required.

It should instead just throw an exception if onError is called (since this is blocking) and onCompleted is not needed because it blocks.

http://msdn.microsoft.com/en-us/library/hh211815(v=vs.103).aspx

@benjchristensen
Copy link
Member

See pull request #147 for more on this.

@benjchristensen
Copy link
Member

Thank you @dcapwell for your work on this!

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

Successfully merging this pull request may close these issues.

2 participants