Skip to content

Subjects reimplemented.#605

Closed
akarnokd wants to merge 1 commit intoReactiveX:masterfrom
akarnokd:SubjectReimpl
Closed

Subjects reimplemented.#605
akarnokd wants to merge 1 commit intoReactiveX:masterfrom
akarnokd:SubjectReimpl

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.

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.

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.

5 participants