SafeSubscriber does not unsubscribe itself
See original GitHub issueWhen subscribing to Observable with Partial Observer, rxjs creates SafeSubscriber, but on unsubscribe it does not unsubscribe itself. Moreover if a closure is passed to next/error callback of partial observer, this leads to memory leaks, as consumers cannot be freed.
See the code (pure JS).
RxJS version: 5.4.1
Code to reproduce:
via gist: https://gist.github.com/czterocyty/d4ad5dea55316c9a734c64f378975f04
Expected behavior:
I think SafeSubscriber#unsubscribe should be called too upon unsubscription.
Test should pass:
it('upon subscription, the destination SafeSubscriber should be unsubscribed too', () => {
const observer = {
next: function () { /*noop*/ },
error: function (e) { throw e; }
};
const sub = new Subscriber(observer);
const destination = sub['destination'];
const destUnsubscribe = destination['unsubscribe'] = sinon.spy();
const destUnsubscribeProtected = destination['_unsubscribe'] = sinon.spy();
sub.unsubscribe();
expect(sub.closed).to.eq(true);
expect(destination.closed).to.eq(true);
expect(destUnsubscribe).have.been.called;
expect(destUnsubscribeProtected).have.been.called;
});
Actual behavior:
It is not when passing partial observer into Subscriber.
Additional information:
After playing around with buttons, check JS heap and not-freed Foo instance due to handing closures in SafeSubscriber. See https://drive.google.com/open?id=0B4JH51FD7JBZcUJTTVRjRXJ2a00. There is Subscriber which is closed (good), but destination as SafeSubscriber is still not closed.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:8
- Comments:18 (6 by maintainers)
Here ya go everybody https://github.com/ReactiveX/rxjs/pull/5311
(For my own reference) this issue is somewhat related to this one: https://github.com/ReactiveX/rxjs/pull/5243