diff --git a/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs b/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs
index 756089f3c..c585ce685 100644
--- a/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs
+++ b/src/modules/Elsa.Workflows.Runtime/HealthChecks/ElsaDistributedLockHealthCheck.cs
@@ -1,5 +1,6 @@
using Elsa.Common;
using Medallion.Threading;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace Elsa.Workflows.Runtime.HealthChecks;
@@ -7,7 +8,7 @@ namespace Elsa.Workflows.Runtime.HealthChecks;
///
/// Verifies that the configured distributed lock provider can acquire and release a probe lock.
///
-public class ElsaDistributedLockHealthCheck(IDistributedLockProvider distributedLockProvider) : IHealthCheck
+public class ElsaDistributedLockHealthCheck(IServiceProvider serviceProvider) : IHealthCheck
{
private static readonly string LockName = $"elsa-health-check-{Environment.MachineName}-{Guid.NewGuid():N}";
private static readonly TimeSpan LockAcquisitionTimeout = TimeSpan.FromSeconds(1);
@@ -17,6 +18,15 @@ public class ElsaDistributedLockHealthCheck(IDistributedLockProvider distributed
{
try
{
+ var distributedLockProvider = serviceProvider.GetService();
+ if (distributedLockProvider == null)
+ {
+ return HealthCheckResult.Degraded("Elsa distributed lock provider is not registered.", data: new Dictionary
+ {
+ ["category"] = "distributed-locks"
+ });
+ }
+
await using var handle = await distributedLockProvider.TryAcquireLockAsync(LockName, LockAcquisitionTimeout, cancellationToken);
if (handle == null)
{
diff --git a/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs b/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs
index 297eaa90a..bfebf682e 100644
--- a/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs
+++ b/test/unit/Elsa.Workflows.Runtime.UnitTests/HealthChecks/ElsaDistributedLockHealthCheckTests.cs
@@ -1,5 +1,6 @@
using Elsa.Workflows.Runtime.HealthChecks;
using Medallion.Threading;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using NSubstitute;
@@ -17,7 +18,7 @@ public class ElsaDistributedLockHealthCheckTests
_distributedLockProvider.CreateLock(Arg.Any()).Returns(_distributedLock);
_distributedLock.TryAcquireAsync(Arg.Any(), Arg.Any())
.Returns(new ValueTask(Substitute.For()));
- _sut = new ElsaDistributedLockHealthCheck(_distributedLockProvider);
+ _sut = new ElsaDistributedLockHealthCheck(CreateServiceProvider(_distributedLockProvider));
}
[Fact]
@@ -53,4 +54,25 @@ public class ElsaDistributedLockHealthCheckTests
Assert.Equal(HealthStatus.Unhealthy, result.Status);
Assert.Equal("distributed-locks", result.Data["category"]);
}
+
+ [Fact]
+ public async Task ReturnsDegradedWhenProviderIsNotRegistered()
+ {
+ var sut = new ElsaDistributedLockHealthCheck(CreateServiceProvider());
+
+ var result = await sut.CheckHealthAsync(new HealthCheckContext());
+
+ Assert.Equal(HealthStatus.Degraded, result.Status);
+ Assert.Equal("distributed-locks", result.Data["category"]);
+ }
+
+ private static IServiceProvider CreateServiceProvider(IDistributedLockProvider? distributedLockProvider = null)
+ {
+ var services = new ServiceCollection();
+
+ if (distributedLockProvider != null)
+ services.AddSingleton(distributedLockProvider);
+
+ return services.BuildServiceProvider();
+ }
}