Skip to content

Commit d5a69e9

Browse files
committed
Depend on IMessageWatchdog so QueueManager can be stubbed in tests
Extract an IMessageWatchdog interface (just RemoveMessages) that MessageWatchdog implements, and have QueueManager depend on it. The hand-rolled QueueManager tests now pass a one-line no-op stub instead of constructing a fully wired MessageWatchdog. Production still injects the real watchdog (non-null).
1 parent a8f1217 commit d5a69e9

4 files changed

Lines changed: 27 additions & 19 deletions

File tree

Core/Cleipnir.ResilientFunctions.Tests/Messaging/TestTemplates/MessagesSubscriptionTests.cs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,14 @@ namespace Cleipnir.ResilientFunctions.Tests.Messaging.TestTemplates;
1818

1919
public abstract class MessagesSubscriptionTests
2020
{
21-
// These tests hand-roll a QueueManager, which now requires a MessageWatchdog. The watchdog is never
22-
// started here, so it only serves QueueManager.RemoveMessages calls (a no-op against its empty ignore-set).
23-
private static MessageWatchdog CreateMessageWatchdog(IFunctionStore functionStore, UnhandledExceptionHandler unhandledExceptionHandler)
24-
=> new(
25-
functionStore.MessageStore,
26-
new FlowsManagers(functionStore),
27-
new ClusterInfo(ReplicaId.NewId()),
28-
new ShutdownCoordinator(),
29-
unhandledExceptionHandler,
30-
checkFrequency: TimeSpan.FromSeconds(1),
31-
delayStartUp: TimeSpan.Zero,
32-
() => DateTime.UtcNow
33-
);
21+
// These tests hand-roll a QueueManager, which depends on IMessageWatchdog only to report deleted message
22+
// positions. They don't exercise that path, so a no-op stub suffices.
23+
private static readonly IMessageWatchdog StubMessageWatchdog = new NoopMessageWatchdog();
24+
25+
private sealed class NoopMessageWatchdog : IMessageWatchdog
26+
{
27+
public void RemoveMessages(IReadOnlyList<long> positions) { }
28+
}
3429

3530
public abstract Task EventsSubscriptionSunshineScenario();
3631
protected async Task EventsSubscriptionSunshineScenario(Task<IFunctionStore> functionStoreTask)
@@ -587,7 +582,7 @@ protected async Task QueueManagerFailsOnMessageDeserializationError(Task<IFuncti
587582
flowTimeouts,
588583
() => DateTime.UtcNow,
589584
SettingsWithDefaults.Default,
590-
CreateMessageWatchdog(functionStore, unhandledExceptionHandler)
585+
StubMessageWatchdog
591586
);
592587

593588
var queueClient = await queueManager.CreateQueueClient();
@@ -651,7 +646,7 @@ protected async Task RegisteredTimeoutIsRemovedWhenPullingMessage(Task<IFunction
651646
minimumTimeout,
652647
() => DateTime.UtcNow,
653648
SettingsWithDefaults.Default,
654-
CreateMessageWatchdog(functionStore, unhandledExceptionHandler)
649+
StubMessageWatchdog
655650
);
656651

657652

@@ -713,7 +708,7 @@ protected async Task PullEnvelopeReturnsEnvelopeWithReceiverAndSender(Task<IFunc
713708
flowTimeouts,
714709
() => DateTime.UtcNow,
715710
SettingsWithDefaults.Default,
716-
CreateMessageWatchdog(functionStore, unhandledExceptionHandler)
711+
StubMessageWatchdog
717712
);
718713

719714
var queueClient = await queueManager.CreateQueueClient();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Collections.Generic;
2+
3+
namespace Cleipnir.ResilientFunctions.CoreRuntime.Watchdogs;
4+
5+
/// <summary>
6+
/// The slice of <see cref="MessageWatchdog"/> a QueueManager depends on: reporting message positions it has
7+
/// deleted from the store so the watchdog can drop them from its ignore-set. Exists so tests that hand-roll a
8+
/// QueueManager can pass a no-op stub instead of a fully wired watchdog.
9+
/// </summary>
10+
internal interface IMessageWatchdog
11+
{
12+
void RemoveMessages(IReadOnlyList<long> positions);
13+
}

Core/Cleipnir.ResilientFunctions/CoreRuntime/Watchdogs/MessageWatchdog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace Cleipnir.ResilientFunctions.CoreRuntime.Watchdogs;
1212

13-
internal class MessageWatchdog
13+
internal class MessageWatchdog : IMessageWatchdog
1414
{
1515
private readonly IMessageStore _messageStore;
1616
private readonly FlowsManagers _flowsManagers;

Core/Cleipnir.ResilientFunctions/Queuing/QueueManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ internal class QueueManager : IDisposable
3232
private readonly FlowTimeouts _timeouts;
3333
private readonly UtcNow _utcNow;
3434
private readonly SettingsWithDefaults _settings;
35-
private readonly MessageWatchdog _messageWatchdog;
35+
private readonly IMessageWatchdog _messageWatchdog;
3636
private readonly IdempotencyKeys _idempotencyKeys;
3737

3838
private readonly SemaphoreSlim _initializeSemaphore = new(1);
@@ -57,7 +57,7 @@ public QueueManager(
5757
FlowTimeouts timeouts,
5858
UtcNow utcNow,
5959
SettingsWithDefaults settings,
60-
MessageWatchdog messageWatchdog,
60+
IMessageWatchdog messageWatchdog,
6161
int maxIdempotencyKeyCount = 100,
6262
TimeSpan? maxIdempotencyKeyTtl = null)
6363
{

0 commit comments

Comments
 (0)