rxjs: Observable memory leak with long polling

I am trying to do a long polling example using angular2 and observables. I had basically this snippet in order to perform the long polling.

(<KitchenSinkOperators<any>>Observable.interval(50))
            .exhaustMap(() => this.getResourceFromBackend('state'))
            .map((resource) => resource.value)
            .distinctUntilChanged()
            .startWith(0);

This code created a MASSIVE memory leak when run in my various browsers, it kept climbing and climbing.

Yet, when I change that code out to do the same thing with Observable.create, everything works as expected. This is the converted version of the above code:

return Observable.create((subscriber: Subscriber<number>) => {
            let register = 0;
            let subscription: Subscription = null;
            // Set an initial value of 0
            subscriber.next(register);

            let interval = setInterval(() => {
                if(subscription === null) {
                    subscription = this.getResourceFromBackend('state')
                        .subscribe(({value}) => {
                            if (<number>value !== register)
                                subscriber.next(register = <number>value);
                        }, (err: any) => subscriber.error(err), () => { subscription.unsubscribe(); subscription = null; });
                }
            }, 50);

            return () => {
                clearInterval(interval);
                if(subscription !== null)
                    subscription.unsubscribe();
            }
        });

Am I misunderstanding something about how Observables and their operators work? Or is there truly a bug here that needs to be fixed? For now it seems I have to stick with my custom implementation, although I would rather not if we can fix the initial code.

Thank you very much,

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 1
  • Comments: 32 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks @aalbericio for the hint. Running the subscription outside the angular zone was the solution for me. I hit this problem while subscribing to multiple source.skipWhile(…).takeWhile(…) where source was created with Observable.interval(100). About a minute after running this the chormium instance inside Electron became completely unresponsive. I tried to reduce the number of subscriptions to see what happens but it didn’t seem to change anything.

I am using

  • Angular 4.4.0-RC.0
  • RxJS 5.4.3
  • Zone.js 0.8.17

Is it possible that we’re hitting this bug again?

I mean, we’re using Angular 4.3.1, RxJS 5.4.1 and Zone 0.8.11

This simple subscription is creating a leak:

this._timeSubscription = Observable.interval(1000).subscribe(x => this.getCurrentTime());

What’s more interesting is that running the subscription outside the angular zone (runOutsideAngular) plus manually detectingChanges does the trick!

Can someone confirm this?

Thanks!