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

Subjects reimplemented. #605

Closed
wants to merge 1 commit into from
Closed

Conversation

akarnokd
Copy link
Member

Reimplemented all 4 kinds of subjects with the following properties:

  • The onNext, onError and onCompleted are fully thread safe against subscription and unsubscription.
  • A terminated subject won't accept any new events; AsyncSubject, PublishSubject and BehaviorSubject will re-emit just the very first exception when an observer subscribes to them.
  • Emitting events to subscribed observers is done while holding the state lock.
    • In Rx.NET when an event is received, the list of observers is retrieved while holding the lock, then outside the lock, the list is traversed and the events are propagated to the observers. Note however, if an observer unsubscribes right after the unlock and before the event propagation, it will still appear in the list and will receive the event. IMO, this is an undesired behavior.
    • The drawback of my solution is that it might be possible to deadlock the subjects, i.e., when an observer deliberately passes the source subject to another thread (which sends an event to the subject) and waits for its completion.
  • Added the Notification.acceptSafe which will capture the exception of the onNext and propagate it through the onError. Its return value indicates if the observer can still be used after (i.e., no terminal event was delivered).
  • Added the reusable state classes to AbstractSubject, although none of the subjects use this class any more.
  • There is an UnsubscribeTester class, which seems to be out-of-place. Can this be moved into the test directory?

@cloudbees-pull-request-builder

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

@daveray
Copy link
Contributor

daveray commented Dec 11, 2013

Holding the lock while dispatching events (i.e. executing arbitrary code) seems pretty dangerous. In my experience I've always ended up regretting it when I did this.

@headinthebox
Copy link
Contributor

"... In Rx.NET when an event is received, the list of observers is retrieved while holding the lock, then outside the lock, the list is traversed and the events are propagated to the observers. Note however, if an observer unsubscribes right after the unlock and before the event propagation, it will still appear in the list and will receive the event. IMO, this is an undesired behavior ...".

Unsubscribing does a "best effort", don't hold the lock.

* @return false if a terminal condition was reached, i.e.,
* this is an isOnCompleted, isOnError or the observer.onNext threw
*/
public boolean acceptSafe(Observer<? super T> observer) {
Copy link
Member

Choose a reason for hiding this comment

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

This is repeating what SafeObserver does. A Notification doesn't need to do anything different and thus we shouldn't be replicating that logic.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay.

@benjchristensen
Copy link
Member

@akarnokd Thanks for this ... @headinthebox and I are reviewing and will end up with some merged/refactored form. So this specific PR won't be merged.

@akarnokd
Copy link
Member Author

No problem.

};
Replayer rp = new Replayer(obs, s);
replayers.put(s, rp);
rp.replayTill(values.size());
Copy link
Member

Choose a reason for hiding this comment

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

This is called from inside the lock being held which means that replaying all historical values to a new Observer will block all existing Observers and new values from proceeding.

Copy link
Member Author

Choose a reason for hiding this comment

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

True. It would need something like the start-once processQueue in observeOn,

@benjchristensen
Copy link
Member

Based on this discussion I've tried my hand in pull request #651

I'd appreciate your review.

@akarnokd
Copy link
Member Author

Sure.

@benjchristensen
Copy link
Member

Closing as we ended up doing this in #651.

Thank you very much for the work on this and the significant performance gains you helped achieve!

@akarnokd akarnokd deleted the SubjectReimpl branch January 13, 2014 10:02
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

5 participants