dotnet / dotnet/reactive

Replay().RefCount() keeps values after all subscriptions are disposed

Open
#1,218 6 comments 3 reactions 0 assignees View on GitHub
[area] Rx
Dominant language
C#
Stars
7.2k
Forks
798
PR merge metrics
No merged PRs in 30d

Description

I use Replay().RefCount() and have several subscribers to it. After all subscribers are unsubscribed original observable stops producing values. After that I subscribe to it again. The new subscriber receives old values of Replay(). It also doesn't have values produced in the interval when there were no subscribers.
For this test:
```c#
[Fact]
public void RefCount_Replay()
{
var subject = new Subject();
var obs = Observable.Create(subscriber =>
{
testOutputHelper.WriteLine("Create");
var subscription = subject.Do(subscriber.OnNext).Subscribe();
return () =>
{
subscription.Dispose();
testOutputHelper.WriteLine("Dispose");
};
});
var shared = obs
.Do(val => testOutputHelper.WriteLine($"publish value: {val}"))
.Replay().RefCount();

subject.OnNext(1);

testOutputHelper.WriteLine(string.Empty);
var subscriber1 = shared.Subscribe(val => testOutputHelper.WriteLine($"subscriber #1: {val}"));

subject.OnNext(2);

testOutputHelper.WriteLine(string.Empty);
var subscriber2 = shared.Subscribe(val => testOutputHelper.WriteLine($"subscriber #2: {val}"));

subject.OnNext(3);

testOutputHelper.WriteLine(string.Empty);
subscriber1.Dispose();
subscriber2.Dispose();

subject.OnNext(4);

testOutputHelper.WriteLine(string.Empty);
var subscriber3 = shared.Subscribe(val => testOutputHelper.WriteLine($"subscriber #3: {val}"));

subject.OnNext(5);
}
```
I receive output:
```
Create
publish value: 2
subscriber #1: 2

subscriber #2: 2
publish value: 3
subscriber #1: 3
subscriber #2: 3

Dispose

subscriber #3: 2
subscriber #3: 3
Create
publish value: 5
subscriber #3: 5
```
As you can see 3rd subscriber has values 2 and 3 (it also doesn't have value 4).
I expected, that after all subscribers unsubscribed and something subscribes to it again it will start receiving new values and forget old ones. It looks like the problem is that Replay() uses ReplaySubject, but ReplaySubject stores all values when there were any subscribers.
I'm not sure what is the correct behaviour, but I think it either should "forget" old values or it should produce all of them.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.