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

Fixed the blocking/non-blocking first #520

Merged
merged 6 commits into from
Dec 23, 2013

Conversation

zsxwing
Copy link
Member

@zsxwing zsxwing commented Nov 25, 2013

Hi, this PR fixed the last problem in #423.

  • Observable.first in RxJava is same as Observable.FirstAsync in Rx.Net, which is a non-blocking operator. When the source sequence is empty, it will emit an IllegalArgumentException.
  • Observable.takeFirst is an alias of take(1). If the source sequence is empty, it will return an empty sequence.
  • BlockingObservable.first in RxJava is same as Observable.First in Rx.Net, which is a blocking operator. When the source sequence is empty, it will emit an IllegalArgumentException.
  • also added BlockingObservable.firstOrDefault.

Here I attached my test codes for Rx.Net.

            Console.WriteLine("===Test FirstAsync");
            {
                IObservable<int> obs = Observable.Range(1, 4).FirstAsync();
                obs.Subscribe(
                    x => Console.WriteLine("FirstAsync: " + x),
                    e => Console.WriteLine("FirstAsync: " + e),
                    () => Console.WriteLine("FirstAsync completed")
                    );
            }
            {
                IObservable<int> obs = Observable.Empty<int>().FirstAsync();
                obs.Subscribe(
                    x => Console.WriteLine("FirstAsync with empty: " + x),
                    e => Console.WriteLine("FirstAsync with empty: " + e),
                    () => Console.WriteLine("FirstAsync with empty completed")
                    );
            }
            Console.WriteLine("===Test Take(1)");
            {
                IObservable<int> obs = Observable.Range(1, 4).Take(1);
                obs.Subscribe(
                    x => Console.WriteLine("Take(1): " + x),
                    e => Console.WriteLine("Take(1): " + e),
                    () => Console.WriteLine("Take(1) completed")
                    );
            }
            {
                IObservable<int> obs = Observable.Empty<int>().Take(1);
                obs.Subscribe(
                    x => Console.WriteLine("Take(1) with empty: " + x),
                    e => Console.WriteLine("Take(1) with empty: " + e),
                    () => Console.WriteLine("Take(1) with empty completed")
                    );
            }
            Console.WriteLine("===Test First(1)");
            {
                int value = Observable.Range(1, 4).First();
                Console.WriteLine("First: " + value);
            }
            {
                try
                {
                    int value = Observable.Empty<int>().First();
                }
                catch(Exception e) {
                    Console.WriteLine("First with empty: " + e);
                }
            }

The output is:

===Test FirstAsync
FirstAsync: 1
FirstAsync completed
FirstAsync with empty: System.InvalidOperationException: Sequence contains no elements.
===Test Take(1)
Take(1): 1
Take(1) completed
Take(1) with empty completed
===Test First(1)
First: 1
First with empty: System.InvalidOperationException: Sequence contains no elements.
...

@cloudbees-pull-request-builder

RxJava-pull-requests #448 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

RxJava-pull-requests #452 FAILURE
Looks like there's a problem with this pull request

@benjchristensen
Copy link
Member

This one is on the list for review...

@cloudbees-pull-request-builder

RxJava-pull-requests #460 SUCCESS
This pull request looks good

@benjchristensen
Copy link
Member

The changes look good ... basically correcting misunderstandings of first , take, firstAsync etc.

@headinthebox Can you weigh in on this?

@cloudbees-pull-request-builder

RxJava-pull-requests #492 SUCCESS
This pull request looks good

@zsxwing
Copy link
Member Author

zsxwing commented Dec 5, 2013

I rebased it on the latest codes.

By the way, @benjchristensen , if you have time, could you close the enhancement issues which have already finished. It's very helpful to find out what is remaining on the TODO list.
I checked the opening issues today. Here is the issues I think can be closed:
#14 #15 #22 #23 #24 #25 #32 #38 #39 #41 #56 #61 #63 #68 #69 #78 #79 #80 #82 #83 #88 #90 #91 #98 #99 #100

@zsxwing
Copy link
Member Author

zsxwing commented Dec 5, 2013

Sorry that my comment messed up the issues. Is there some way to delete the references in other issues?

@headinthebox
Copy link
Contributor

Quick question, is it worthwhile to have an alias for take(1) that is actually longer takeFirst()?
The reason the operation existed was because we wanted first.
So let's remove all trivial ones.

@zsxwing
Copy link
Member Author

zsxwing commented Dec 6, 2013

I'm OK to remove takeFirst. But I worry about breaking the existed public API.

@benjchristensen
Copy link
Member

We can mark it deprecated right now if we want to remove it.

On Dec 6, 2013, at 1:39 PM, Shixiong Zhu notifications@github.com wrote:

I'm OK to remove takeFirst. But I worry about breaking the existed public API.


Reply to this email directly or view it on GitHub.

*/
public Observable<T> takeFirst(Func1<? super T, Boolean> predicate) {
return first(predicate);
return skipWhile(not(predicate)).take(1);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this overload of takeFirst, I suppose we should reserve it.

@cloudbees-pull-request-builder

RxJava-pull-requests #504 SUCCESS
This pull request looks good

@zsxwing
Copy link
Member Author

zsxwing commented Dec 9, 2013

Rebased it. Any further suggestion?

@cloudbees-pull-request-builder

RxJava-pull-requests #526 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

RxJava-pull-requests #564 SUCCESS
This pull request looks good

@zsxwing zsxwing mentioned this pull request Dec 18, 2013
53 tasks
@cloudbees-pull-request-builder

RxJava-pull-requests #571 FAILURE
Looks like there's a problem with this pull request

@zsxwing
Copy link
Member Author

zsxwing commented Dec 19, 2013

I implemented the non-blocking single and singeOrDefault and used them to reimplement the blocking/nonblocking single, singleOrDefault, first, firstOrDefault, last, lastOrDefault. Here are the differences between these operators:

RxJava operators more than one items in the input sequence one item in the input sequence empty sequence method name in Rx.Net
Observable.single IllegalArgumentException the single item IllegalArgumentException singleAsync
BlockingObservable.single IllegalArgumentException the single item IllegalArgumentException single
Observable.singleOrDefault IllegalArgumentException the single item the default value singleOrDefaultAsync
BlockingObservable.singleOrDefault IllegalArgumentException the single item the default value singleOrDefault
Observable.first the first item the first item IllegalArgumentException firstAsync
BlockingObservable.first the first item the first item IllegalArgumentException first
Observable.firstOrDefault the first item the first item the default value firstOrDefaultAsync
BlockingObservable.firstOrDefault the first item the first item the default value firstOrDefault
Observable.last the last item the last item IllegalArgumentException lastAsync
BlockingObservable.last the last item the last item IllegalArgumentException last
Observable.lastOrDefault the last item the last item the default value lastOrDefaultAsync
BlockingObservable.lastOrDefault the last item the last item the default value lastOrDefault

I changed public Observable<T> firstOrDefault(Func1<? super T, Boolean> predicate, T defaultValue) to public Observable<T> firstOrDefault(T defaultValue, Func1<? super T, Boolean> predicate) to keep these operators consistent. However, it breaks the previous API.

@cloudbees-pull-request-builder

RxJava-pull-requests #572 SUCCESS
This pull request looks good

@cloudbees-pull-request-builder

RxJava-pull-requests #575 SUCCESS
This pull request looks good


private volatile T value;
private volatile boolean isEmpty = true;
private volatile boolean hasTooManyElemenets;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these don't need to be volatiles.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed "volatile". Thanks!

@cloudbees-pull-request-builder

RxJava-pull-requests #576 SUCCESS
This pull request looks good

@benjchristensen
Copy link
Member

Excellent table explaining what this is all did!

@DavidMGross Can you validate all of our documentation on these operators aligns with that table above?

benjchristensen added a commit that referenced this pull request Dec 23, 2013
Fixed the blocking/non-blocking first
@benjchristensen benjchristensen merged commit cfb8f5f into ReactiveX:master Dec 23, 2013
@benjchristensen
Copy link
Member

Thank you @zsxwing. This is a good set of fixes.

@zsxwing zsxwing deleted the first branch December 24, 2013 02:45
@DavidMGross
Copy link
Collaborator

I've looked over the Wiki docs & javadocs and both seem to be aligned with
the table now. I've also added the table itself as an appendix to the
BlockingObservable wiki page, here:

https://github.com/Netflix/RxJava/wiki/Blocking-Observable-Operators#appendix-similar-blocking-and-non-blocking-operators

On Mon, Dec 23, 2013 at 12:51 PM, Ben Christensen
notifications@github.comwrote:

Thank you @zsxwing https://github.com/zsxwing. This is a good set of
fixes.


Reply to this email directly or view it on GitHubhttps://github.com//pull/520#issuecomment-31143126
.

David M. Gross
PLP Consulting

@zsxwing
Copy link
Member Author

zsxwing commented Dec 27, 2013

Great work. Thanks, @DavidMGross

rickbw pushed a commit to rickbw/RxJava that referenced this pull request Jan 9, 2014
Fixed the blocking/non-blocking first
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.

None yet

6 participants