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.

Task order for Observable.combineLatest and Schedulers.computation()

See original GitHub issue

Version: 1.3.0

Hello!

I have observed strange behavior while I was using combineLatest with Schedulers.computation(). Please take a look at example:

   private static void runSubscription(String prefix, boolean shouldWait, ConcurrentMap<String, Integer> stat) {
        Observable<Long> interval = Observable.interval(1000, TimeUnit.MILLISECONDS);
        Observable.combineLatest(Observable.just(prefix), interval, (s1, s2) -> s1)
            .subscribeOn(Schedulers.computation())
            .observeOn(Schedulers.computation())
            .onBackpressureLatest()
            .subscribe(s -> {
                try {
                    if (shouldWait) {
                        Thread.sleep(4000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                stat.merge(s, 1, (v1, v2) -> v1 + v2);
            });
    }

    public static void main(String[] args) throws Exception {
        ConcurrentMap<String, Integer> stat = new ConcurrentHashMap<>();

        stat.put("1", 0);
        runSubscription("1", true, stat);
        for (int i = 1; i < Runtime.getRuntime().availableProcessors(); i++) {
            String key = String.valueOf(i + 1);
            stat.put(key, 0);
            runSubscription(key, false, stat);
        }

        while (!Thread.currentThread().isInterrupted()) {
            // Print invocation statistics
            System.out.println(stat);
            Thread.sleep(4000);
        }
    }

The output shows how many times particular subscriber was invoked. First column - subscriber number, second - invocation count. For version above output is:

{1=0, 2=0, 3=0, 4=0}
{1=0, 2=1, 3=1, 4=3}
{1=1, 2=1, 3=1, 4=7}
{1=2, 2=1, 3=1, 4=11}
{1=3, 2=1, 3=1, 4=15}
{1=4, 2=1, 3=1, 4=19}
{1=5, 2=1, 3=1, 4=23}
{1=6, 2=1, 3=1, 4=27}
{1=7, 2=1, 3=1, 4=31}
...

The output is not stable, but every time some of threads invoked less times. But when I changed both Schedulers.computation() to Schedulers.io(), output changed to expected:

{1=0, 2=0, 3=0, 4=0}
{1=0, 2=3, 3=3, 4=3}
{1=1, 2=7, 3=7, 4=7}
{1=2, 2=11, 3=11, 4=11}
{1=3, 2=15, 3=15, 4=15}
{1=4, 2=19, 3=19, 4=19}

Is it incorrect usage of scheduler, or it is a bug?

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
akarnokdcommented, Aug 22, 2017

The computation scheduler has a number of worker threads that is, by default, is equal to the number of available processors and hands out worker threads in a round robin fashion. Since there is a limited number of them and you block one of them in your first run, the subsequent runs will likely get that scheduler and block tasks behind it.

You are practically wasting schedulers as subscribeOn in this case has no effect, interval already runs on the computation scheduler and observeOn moves the events from one computation worker to another without much benefit.

0reactions
timofeevdacommented, Aug 23, 2017

OK, thanks for explanation.

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Unit test of RxJava combineLatest hangs when single thread ...
This testcase hangs when executed. If I remove the scheduler hook, it runs fine. Any idea why this is case and how can...
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 >
Advanced RxJava programming with stream nesting - Medium
When we schedule a periodic job on the worker, it requires a callback Runnable to call the run() method each time a period...
Read more >
Primer on RxJS Schedulers - André Staltz
Schedulers in RxJS are things that control the order of event ... combineLatest(a$, b$, (a, b) => a + b); c$.subscribe(c => console.log(c));....
Read more >
Exploring RxJava in Android
An onNext() method that the Observable calls whenever it wishes to publish a ... Schedulers.computation() this gives us a Scheduler that is ...
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