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

Observable is not respecting subscribeOn #430

Closed
doapp-grady opened this Issue Mar 7, 2014 · 9 comments

Comments

4 participants
@doapp-grady

doapp-grady commented Mar 7, 2014

In an Android app, I am using retrofit's observables. I am running into an issue where the observable is not respecting my observeOn. Here is what I am hoping my code would look like:

@get("/foo.gz")
public Observable getFoo();
...

RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://fooprovider.com")
.build();
FooApi apiManager = restAdapter.create(FooApi.class);
apiManager.getFoo()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SettingsObserver(this));

Right now I believe I have a few options to get network off the main thread. I can wrap this in a callable which executes on a different thread. I can have my Api return Foo and build my own Observable. Or I can pass in an httpExecutor and callbackExecutor to my restAdapter.

I feel like none of those solutions look as clean as my sample code.

@JakeWharton

This comment has been minimized.

Show comment
Hide comment
@JakeWharton

JakeWharton Mar 7, 2014

Collaborator

Two things:

  • Don't call subscribeOn. We do that for you using the internal HTTP Executor of the RestAdpater.
  • All we do is wrap a synchronous Retrofit call in a normal Observable and hand it back to you. The semantics of what happens is all the RxJava library.

We do this many times:

apiManager.getFoo()
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(u -> println(u))

and it works perfectly.

Collaborator

JakeWharton commented Mar 7, 2014

Two things:

  • Don't call subscribeOn. We do that for you using the internal HTTP Executor of the RestAdpater.
  • All we do is wrap a synchronous Retrofit call in a normal Observable and hand it back to you. The semantics of what happens is all the RxJava library.

We do this many times:

apiManager.getFoo()
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(u -> println(u))

and it works perfectly.

@JakeWharton

This comment has been minimized.

Show comment
Hide comment
@JakeWharton

JakeWharton Mar 12, 2014

Collaborator

Any updates on this? I'm going to preemptively close since I'm quite confident that this is working and it's just a user disconnect or application-level bug.

Collaborator

JakeWharton commented Mar 12, 2014

Any updates on this? I'm going to preemptively close since I'm quite confident that this is working and it's just a user disconnect or application-level bug.

@briandilley

This comment has been minimized.

Show comment
Hide comment
@briandilley

briandilley Feb 24, 2016

@JakeWharton is this still true of retrofit 2?

briandilley commented Feb 24, 2016

@JakeWharton is this still true of retrofit 2?

@briandilley

This comment has been minimized.

Show comment
Hide comment
@briandilley

briandilley Feb 24, 2016

I think i see in RxJavaCallAdapterFactory where we can specify the default scheduler... i assume that's what i should use then.

briandilley commented Feb 24, 2016

I think i see in RxJavaCallAdapterFactory where we can specify the default scheduler... i assume that's what i should use then.

@JakeWharton

This comment has been minimized.

Show comment
Hide comment
@JakeWharton

JakeWharton Feb 24, 2016

Collaborator

2 is synchronous by default

On Wed, Feb 24, 2016 at 5:41 PM Brian notifications@github.com wrote:

I think i see in RxJavaCallAdapterFactory where we can specify the
default scheduler... i assume that's what i should use then.


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

Collaborator

JakeWharton commented Feb 24, 2016

2 is synchronous by default

On Wed, Feb 24, 2016 at 5:41 PM Brian notifications@github.com wrote:

I think i see in RxJavaCallAdapterFactory where we can specify the
default scheduler... i assume that's what i should use then.


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

@briandilley

This comment has been minimized.

Show comment
Hide comment
@briandilley

briandilley Feb 24, 2016

Ok, so then i need to call subscribeOn(Schedulers.io()) to make sure the network call happens on the IO thread. And the code in master has a way to set a default scheduler for RxJavaCallAdapterFactory via: RxJavaCallAdapterFactory.create(Schedulers.io())

briandilley commented Feb 24, 2016

Ok, so then i need to call subscribeOn(Schedulers.io()) to make sure the network call happens on the IO thread. And the code in master has a way to set a default scheduler for RxJavaCallAdapterFactory via: RxJavaCallAdapterFactory.create(Schedulers.io())

@JakeWharton

This comment has been minimized.

Show comment
Hide comment
@JakeWharton

JakeWharton Feb 24, 2016

Collaborator

Yep! You got it.

On Wed, Feb 24, 2016 at 5:43 PM Brian notifications@github.com wrote:

Ok, so then i need to call subscribeOn(Schedulers.io()) to make sure the
network call happens on the IO thread. And the code in master has a way
to set a default scheduler for RxJavaCallAdapterFactory via:
RxJavaCallAdapterFactory.create(Schedulers.io())


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

Collaborator

JakeWharton commented Feb 24, 2016

Yep! You got it.

On Wed, Feb 24, 2016 at 5:43 PM Brian notifications@github.com wrote:

Ok, so then i need to call subscribeOn(Schedulers.io()) to make sure the
network call happens on the IO thread. And the code in master has a way
to set a default scheduler for RxJavaCallAdapterFactory via:
RxJavaCallAdapterFactory.create(Schedulers.io())


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

@lukaszkalnik

This comment has been minimized.

Show comment
Hide comment
@lukaszkalnik

lukaszkalnik May 6, 2016

Just to clarify: is it enough to just set default scheduler in my Retrofit object by calling RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()) (making the call asynchronous) or should I also later call subscribeOn(Schedulers.io()) when subscribing to the created Retrofit Observable?

Do these calls effectively duplicate each other's behavior in this case?

My goal is simply to make an async network call and report the result back to the main thread.

lukaszkalnik commented May 6, 2016

Just to clarify: is it enough to just set default scheduler in my Retrofit object by calling RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()) (making the call asynchronous) or should I also later call subscribeOn(Schedulers.io()) when subscribing to the created Retrofit Observable?

Do these calls effectively duplicate each other's behavior in this case?

My goal is simply to make an async network call and report the result back to the main thread.

@JakeWharton

This comment has been minimized.

Show comment
Hide comment
@JakeWharton

JakeWharton May 6, 2016

Collaborator

Do these calls effectively duplicate each other's behavior in this case?

yes

Collaborator

JakeWharton commented May 6, 2016

Do these calls effectively duplicate each other's behavior in this case?

yes

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