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

Calling to Observable.toBlocking(). Always a bad practice? #3956

Closed
VictorAlbertos opened this issue May 20, 2016 · 5 comments
Closed

Calling to Observable.toBlocking(). Always a bad practice? #3956

VictorAlbertos opened this issue May 20, 2016 · 5 comments
Labels

Comments

@VictorAlbertos
Copy link
Contributor

Hi.

I have a library which returns observables. And I have another one which require to return the data in a synchronous way.

Particularly, I’m talking about OkHttp Interceptors. I need to retrieve the oauth token in order to add it as header. But this data comes from an observable.

public class TwitterInterceptor implements Interceptor {
    @Override public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request newRequest = request.newBuilder()
                .addHeader("oauth_token", RxToken.getTwitterToken().toBlocking().first())
                .build();
        return chain.proceed(newRequest);
    }
}

Calling toBlocking().first() is the only way I can think to solve this problem. But I do not know if calling toBlocking() may have some unexpected effects (I mean I know that this observable resolves its task reading from disk or memory, so it is not a really heavy task). But because it seems to be not recommended to use it in production code, as a general rule.

Thanks.

@akarnokd
Copy link
Member

toBlocking gets you out of the reactive world and is generally fine if you have to bridge legacy, non-reactive APIs with it. In your example, if you can't change the method to Observable<Response> intercept(Chain chain), toBlocking is acceptable tradeoff.

However, if you are in the reactive world and suddenly want to use toBlocking inside a sequence, there are almost always ways to not do that. A typical mistake that comes up is something like this:

source.map(v -> someAPI(v).toBlocking().first())...

Instead, you should be using any of the flatMap, concatMap, etc.

source.concatMap(v -> someAPI(v))...

@VictorAlbertos
Copy link
Contributor Author

Thanks for the explanation David.

@tomgallagher
Copy link

I've got a question about this. In Android, shouldInterceptRequest on a WebClient requires a returned value, either null or a WebResourceResponse. I would like to avoid having a blockingFirst() call. Ideally I would like to pass a reference to the return value into the Observable chain and then make the decision on blocking later on. But I can't see how to do this.

@akarnokd
Copy link
Member

@tomgallagher almost always is. If you have something specific, please ask the wider audience of StackOverflow about it.

@tomgallagher
Copy link

OK thanks.

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

No branches or pull requests

3 participants