fix(sessions): tidy replay filter/comment; zero OldestAvailableSequence when no gap
- EventStreamService: remove dead per-item sequence guard in the replay loop (RegisterWithReplay already returns only events > afterSequence) and correct the comment that falsely claimed a "per-item constraint filter" is applied; the event stream has no per-event constraint filtering today. - SessionEventDistributor.RegisterWithReplay: set oldestAvailableSequence=0 when gap==false so the implementation matches the documented contract (OldestAvailableSequence is meaningful only when Gap is true). Update the two RegisterWithReplay tests that asserted the old non-zero value in the no-gap path. - RegisterSubscriber: remove stray blank line at method entry. - SessionEventDistributorTests: add RegisterWithReplay_AfterDispose_ ThrowsObjectDisposedException to pin nested-lock disposal behavior.
This commit is contained in:
@@ -113,6 +113,27 @@ public sealed class SessionEventDistributorTests
|
||||
Assert.Throws<ObjectDisposedException>(() => distributor.Register());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RegisterWithReplay_AfterDispose_ThrowsObjectDisposedException()
|
||||
{
|
||||
// Pins the nested-lock disposal behavior in RegisterWithReplay: the inner
|
||||
// _lifecycleLock check must surface ObjectDisposedException even when the outer
|
||||
// _replayLock snapshot succeeds on a disposed distributor.
|
||||
Channel<MxEvent> source = Channel.CreateUnbounded<MxEvent>();
|
||||
SessionEventDistributor distributor = CreateDistributor(source.Reader);
|
||||
await distributor.StartAsync(CancellationToken.None);
|
||||
|
||||
await distributor.DisposeAsync().AsTask().WaitAsync(ReadTimeout);
|
||||
|
||||
Assert.Throws<ObjectDisposedException>(() =>
|
||||
distributor.RegisterWithReplay(
|
||||
0,
|
||||
out _,
|
||||
out _,
|
||||
out _,
|
||||
out _));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReplayBuffer_OverCapacity_EvictsOldestFirst_AndReportsGap()
|
||||
{
|
||||
@@ -601,7 +622,8 @@ public sealed class SessionEventDistributorTests
|
||||
Assert.False(gap);
|
||||
Assert.Equal(new ulong[] { 3, 4, 5 }, replay.Select(e => e.WorkerSequence));
|
||||
Assert.Equal(5ul, liveResume);
|
||||
Assert.Equal(1ul, oldestAvailable);
|
||||
// OldestAvailableSequence is 0 when gap == false (meaningful only when gap is true).
|
||||
Assert.Equal(0ul, oldestAvailable);
|
||||
|
||||
// A subsequent live event flows to the resumed subscriber's channel.
|
||||
source.Writer.TryWrite(Event(6));
|
||||
@@ -669,7 +691,8 @@ public sealed class SessionEventDistributorTests
|
||||
Assert.False(gap);
|
||||
Assert.Empty(replay);
|
||||
Assert.Equal(3ul, liveResume);
|
||||
Assert.Equal(1ul, oldestAvailable);
|
||||
// OldestAvailableSequence is 0 when gap == false (meaningful only when gap is true).
|
||||
Assert.Equal(0ul, oldestAvailable);
|
||||
|
||||
source.Writer.TryWrite(Event(4));
|
||||
MxEvent live = await ReadOneAsync(resume.Reader);
|
||||
|
||||
Reference in New Issue
Block a user