Skip to content

Creating Observable#create overloads for SyncOnSubscribe and AsyncOnSubscribe #3738

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

Merged
merged 1 commit into from
Mar 3, 2016

Conversation

stealthcode
Copy link

This is to facilitate the discovery of methods for creating observables that respect back pressure semantics. Currently the Observable#create(OnSubscribe) static method is the easiest method to discover for creating an observable which does not provide clear facilities for managing back pressure.

@benjchristensen
Copy link
Member

I like this addition. It makes it far more discoverable to do 'create' in a safer way.

+1

@abersnaze
Copy link
Contributor

I'm worried that having the same name will cause method resolution problems with other not so strict JVM languages.

@davidmoten
Copy link
Collaborator

Looks good. @abersnaze what's an example?

* @see <a href="http://reactivex.io/documentation/operators/create.html">ReactiveX operators documentation: Create</a>
*/
public static <S, T> Observable<T> create(SyncOnSubscribe<S, T> syncOnSubscribe) {
return new Observable<T>(hook.onCreate(syncOnSubscribe));
Copy link
Member

Choose a reason for hiding this comment

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

I guess you couldn't call create(OnSubscribe) because of overload problems.

Copy link
Author

Choose a reason for hiding this comment

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

You can still call to the OnSubscribe overload and it would work just fine. The purpose behind the 2 new overloads is discoverability.

@akarnokd
Copy link
Member

akarnokd commented Mar 2, 2016

Sure these two methods point to the classes, but I'd prefer those createStateful and such methods added to Observable instead.

@stealthcode
Copy link
Author

@akarnokd so you would prefer to have the static create methods explicitly listed out? This is how that would look when in an IDE (i.e. in Eclipse with Observable.create then hitting CTRL+Space).

One static method per concrete option:

create(OnSubscribe<T> f)
createAsyncSingleState(Func0<? extends S> generator, Action3<? super S, Long, ? super Observer<Observable<? extends T>>> next)
createAsyncSingleState(Func0<? extends S> generator, Action3<? super S, Long, ? super Observer<Observable<? extends T>>> next, final Action1<? super S> onUnsubscribe)
createAsyncStateful(Func0<? extends S> generator, Func3<? super S, Long, ? super Observer<Observable<? extends T>>, ? extends S> next, Action1<? super S> onUnsubscribe)
createAsyncStateless(Action2<Long, ? super Observer<Observable<? extends T>>> next)
createAsyncStateless(Action2<Long, ? super Observer<Observable<? extends T>>> next, Action0 onUnsubscribe)
createSyncSingleState(Func0<? extends S> generator, Action2<? super S, ? super Observer<? super T>> next)
createSyncSingleState(Func0<? extends S> generator, Action2<? super S, ? super Observer<? super T>> next, Action1<? super S> onUnsubscribe)
createSyncStateful(Func0<? extends S> generator, Func2<? super S, ? super Observer<? super T>, ? extends S> next, Action1<? super S> onUnsubscribe)
createSyncStateful(Func0<? extends S> generator, Func2<? super S, ? super Observer<? super T>, ? extends S> next)
createSyncStateless(Action1<? super Observer<? super T>> next)
createSyncStateless(Action1<? super Observer<? super T>> next, Action0 onUnsubscribe)

One overload per highlevel category (Sync, Async)

create(OnSubscribe<T> f)
create(SyncOnSubscribe<S, T> syncOnSubscribe)
create(AsyncOnSubscribe<S, T> asyncOnSubscribe)

This isn't exactly a direct apples-to-apples representation as you'd have to use the SyncOnSubscribe static methods. e.g.

create(SyncOnSubscribe.createStateless(Action1<? super Observer<? super T>> next))

I think I prefer the latter because the surface area of the Observable is constrained to two (three-ish) high level categories of creation options.

@stealthcode stealthcode force-pushed the generator-return-types branch from 31b87a0 to e2709f0 Compare March 2, 2016 23:42
@stealthcode
Copy link
Author

I've added more explanation to the javadoc.

@stevegury
Copy link
Member

I prefer current version (with overload per high-level category).
👍

@stealthcode stealthcode force-pushed the generator-return-types branch from e2709f0 to 479d1e0 Compare March 3, 2016 18:23
@stealthcode
Copy link
Author

The test seems to be a flaky unit test.

rx.ObservableTests > testErrorThrownIssue1685 FAILED
    java.lang.AssertionError: UncaughtExceptionHandler didn't get anything.
        at org.junit.Assert.fail(Assert.java:93)
        at org.junit.Assert.assertTrue(Assert.java:43)
        at org.junit.Assert.assertNotNull(Assert.java:526)
        at rx.ObservableTests.testErrorThrownIssue1685(ObservableTests.java:1113)

I have added @Experimental to these overloads (to mirror the status of the underlying Sync/Async O.S.). Is this otherwise an acceptable API addition or are there concerns? @akarnokd @abersnaze

@akarnokd
Copy link
Member

akarnokd commented Mar 3, 2016

Travis sometimes seems to slow down drastically; that 1 second wait in that test is like 1000x more than usually needed to verify the behavior. Just rerun the test in this case.

We can start with your two methods and add the rest later.

@stealthcode
Copy link
Author

I would prefer not to have both styles personally as redundancy makes for a cluttered and confusing api. Is it a personal preference for listing all variants?

@akarnokd
Copy link
Member

akarnokd commented Mar 3, 2016

Only the sync ones, the async ones can be hidden behind that create overload.

@stealthcode
Copy link
Author

I'm fine discussing that when the time comes.

stealthcode pushed a commit that referenced this pull request Mar 3, 2016
Creating Observable#create overloads for SyncOnSubscribe and AsyncOnSubscribe
@stealthcode stealthcode merged commit 322fd2f into ReactiveX:1.x Mar 3, 2016
@stealthcode stealthcode deleted the generator-return-types branch March 3, 2016 21:22
@abersnaze
Copy link
Contributor

@davidmoten I can't remember the exact instances of the issue but I'm not as familiar with scala, clojure, groovy, or kotlin. I did a simple test in groovy, that worked, just because I had a REPL handy. it would be nice have a lowest common denominator for method signatures so we don't make it unnecessarily difficult in any of those languages.

@JakeWharton
Copy link
Contributor

Kotlin handles the overloads fine 👍

On Thu, Mar 3, 2016 at 7:26 PM George Campbell [email protected]
wrote:

@davidmoten https://github.com/davidmoten I can't remember the exact
instances of the issue but I'm not as familiar with scala, clojure, groovy,
or kotlin. I did a simple test in groovy, that worked, just because I had a
REPL handy. it would be nice have a lowest common denominator for method
signatures so we don't make it unnecessarily difficult in any of those
languages.


Reply to this email directly or view it on GitHub
#3738 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants