fix(notification-outbox): clear dispatch in-flight flag on a faulted pass
This commit is contained in:
@@ -254,6 +254,28 @@ public class NotificationOutboxActorDispatchTests : TestKit
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FaultedDispatchPass_ClearsInFlightGuard_SoNextTickStillRuns()
|
||||
{
|
||||
SetupSmtpRetryPolicy(maxRetries: 5, retryDelay: TimeSpan.FromMinutes(1));
|
||||
// GetDueAsync throws on every call: the dispatch pass's task could fault if the
|
||||
// failure were not handled, which would leave _dispatching stuck true forever.
|
||||
_outboxRepository.GetDueAsync(Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.Returns<IReadOnlyList<Notification>>(_ => throw new InvalidOperationException("db down"));
|
||||
var actor = CreateActor(new Dictionary<NotificationType, INotificationDeliveryAdapter>());
|
||||
|
||||
// First tick: the pass faults internally but must still clear the in-flight guard.
|
||||
actor.Tell(InternalMessages.DispatchTick.Instance);
|
||||
AwaitAssert(() => _outboxRepository.Received(1).GetDueAsync(
|
||||
Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>()));
|
||||
|
||||
// Second tick after the first completes: if the guard had wedged, this would be
|
||||
// dropped and GetDueAsync would still show only one call.
|
||||
actor.Tell(InternalMessages.DispatchTick.Instance);
|
||||
AwaitAssert(() => _outboxRepository.Received(2).GetDueAsync(
|
||||
Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void OverlappingTicks_WhileDispatchInFlight_DoNotClaimConcurrently()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user