question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Zip behaviour with different schedulers in combining observables

See original GitHub issue

I faced unpredictable behaviour in Zip scheduling. I have observables that supplying items in different schedulers. Zip combine function will be executed when “last” item in set will be supplied by one of observables. Also tick() and then zipFunction.call(…) will be executed in scheduler of “last” observable. It means we don’t know about scheduler where zip combining function will be executed.

For example I have a ConnectableObservable that was started by connect() in main thread. And then I want to combine it with other observables.

//somewhere in main thread
observable1.connect();

//somewhere else
Observable.zip(
    observable1,
    observable2,
    (res1, res2) -> combine(res1, res2)
).subscribeOn(Schedulers.io())

Of course observable2 will be executed in the one of Schedulers.io() threads. But in combining function I have no idea about my current thread. It can be main thread or one of Scheduler.io() threads. It’s quite not logical in some cases.

I suggest to add variations of zip that can operate in specified scheduler, e.g. explicitly pass scheduler to zip operator or make operator like zipMap that will be operating in scheduler you pass to whole Observable.

Any ideas?

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

6reactions
onelaviewcommented, Jan 10, 2017

Hi @franciscojunior

Can you try specifying the scheduler for which a second Single is operating on? e.g.

single1
    .observeOn(mainThreadScheduler)
    .zipWith(single2.subscribeOn(mainThreadScheduler))

or if you use static method version

Single.zip(
    single1.subscribeOn(mainThreadScheduler),
    single2.subscribeOn(mainThreadScheduler),
    (car, engine) -> {
        // do something in main thread
    })

From my observation, I think zip operator’s combine function is being called in a scheduler that the source singles are operating on. If the sources are operating on different scheduler, it is quite uncertain as to which scheduler will be used to run the combine function. I guess it will be a scheduler of a single that emit the latter item for each combination of a zipped items. By specifying mainThreadScheduler to both singles, it will ensure that the combine function will only be run from the main thread.

2reactions
onelaviewcommented, Jan 21, 2017

Hi @franciscojunior

You may try to use .observeOn() on your second observable instead of .subscribeOn() i.e.

single1
    .observeOn(mainThreadScheduler)
    .zipWith(single2.observeOn(mainThreadScheduler))

No matter what scheduler a Single is originally operating on, the observeOn() will instruct it to emit an item on a particular scheduler.

http://reactivex.io/documentation/operators/observeon.html

Read more comments on GitHub >

github_iconTop Results From Across the Web

Concurrent tasks with zip operator | by Giuseppe Villani
The well known zip() operator is a useful tool for executing and combining multiple streams, returning just a single stream of data.
Read more >
Observable.zip chooses different schedulers to subscribe on ...
I have two observables o1 and o2. I zip them over Observable.zip() function, but subscription is every time on different scheduler.
Read more >
Rxjava Combine Observables part 2 ( Merge and Zip )
This is the second part of tutorial Rxjava Combine multiple observables and emit it , Merge and Zip concurrent observers ..
Read more >
RxJava Combining Operators - Kodeco
In this tutorial, you'll use RxJava combining operators to merge, filter and transform your data into succinct and reusable streams.
Read more >
Merge operator - ReactiveX
combine multiple Observables into one by merging their emissions ... that changes this behavior — reserving onError notifications until all of the merged ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found