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.

Reducing inner observable blows stack

See original GitHub issue

For my use case I have the reduce function return an inner observable. A simple test reveals that creating a large enough sequence will result in stack overflow.

RxJS version: 5.5.6

Code to reproduce:

const Observable  = require("rxjs/Rx").Observable;

function add($a,$b) {
	$a = $a instanceof Observable ? $a : Observable.of($a);
	$b = $b instanceof Observable ? $b : Observable.of($b);
	return $a.mergeMap(a => $b.reduce((a,b) => a + b,a));
}

Observable.range(1,1000).reduce(add).mergeAll().subscribe(console.log);

Expected behavior: Log result

Actual behavior: UnsubscriptionError: 1 errors occurred during unsubscription:

  1. RangeError: Maximum call stack size exceeded

Additional information: Tested in Node.js 8.5

This may not be a bug if there’s a workaround, but I couldn’t find / come up with one.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
cartantcommented, May 4, 2018

I think there’s a bit more to this, as the reduce composes an extremely long dot-chained observable and even if the queue scheduler is used, the eventual unsubscription will effect a stack overflow error.

The good news is that you can solve the problem using the queue scheduler, but you need to write a user-land unsubscribeOn operator to ensure that unsubscription does not happen recursively, like this:

Rx.Observable
    .range(0, 5000).reduce(
        (acc$, x) => acc$
          .map(acc => acc + x)
          .subscribeOn(Rx.Scheduler.queue)
          .let(unsubscribeOn(Rx.Scheduler.queue)),
        Rx.Observable.of(0)
    )
    .mergeAll()
    .subscribe({
        next: x => console.log(x),
        error: err => console.error(err),
        complete: () => console.log("complete")
    });

function unsubscribeOn(scheduler) {
    return source => new Rx.Observable(observer => {
        const subscription = source.subscribe(observer);
        return () => scheduler.schedule(() => subscription.unsubscribe());
    });
}
0reactions
lock[bot]commented, Jun 5, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Disposal when chaining Observables from async
If you run this a few times (e.g. with breakpoints, etc), you should see that it blows up because the TextReader is closed....
Read more >
Optimizing Batch Processing Jobs with RxJS | by Ravi Mehra
Batch processing may not appear too exciting. Retrieve some data, do some operations on that data, repeat. They do their job silently and ......
Read more >
How observability is redefining the roles of developers
Using our developer observability tool, we placed a conditional snapshot on a Spring internal class ( TransactionAspectSupport ). We then ...
Read more >
Are We Shooting Ourselves in the Foot with Stack Overflow?
In case of stack overflow you have several options: you might intentionally reduce the size of the stack section so that it is...
Read more >
Observability — A 3-Year Retrospective - The New Stack
Observability, the development approach or moreover the “movement'” is about three years old and Charity Majors, one of the early pioneers ...
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