diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireDynamicBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireDynamicBackgroundWorkerManager.cs index a9b9026606..c3413096bc 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireDynamicBackgroundWorkerManager.cs @@ -18,6 +18,8 @@ public class HangfireDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerMa protected IServiceProvider ServiceProvider { get; } protected IDynamicBackgroundWorkerHandlerRegistry HandlerRegistry { get; } public ILogger Logger { get; set; } + public virtual DynamicBackgroundWorkerManagerCapabilities Capabilities { get; } = + new DynamicBackgroundWorkerManagerCapabilities(); public HangfireDynamicBackgroundWorkerManager( IServiceProvider serviceProvider, diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzDynamicBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzDynamicBackgroundWorkerManager.cs index 5a729ad974..f1c6736e4c 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzDynamicBackgroundWorkerManager.cs @@ -17,6 +17,8 @@ public class QuartzDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerMana protected IScheduler Scheduler { get; } protected IDynamicBackgroundWorkerHandlerRegistry HandlerRegistry { get; } public ILogger Logger { get; set; } + public virtual DynamicBackgroundWorkerManagerCapabilities Capabilities { get; } = + new DynamicBackgroundWorkerManagerCapabilities(); public QuartzDynamicBackgroundWorkerManager( IScheduler scheduler, diff --git a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs index 6976f49cb5..731bd3b1da 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/TickerQDynamicBackgroundWorkerManager.cs @@ -7,6 +7,13 @@ namespace Volo.Abp.BackgroundWorkers.TickerQ; [Dependency(ReplaceServices = true)] public class TickerQDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerManager, ISingletonDependency { + public virtual DynamicBackgroundWorkerManagerCapabilities Capabilities { get; } = + new DynamicBackgroundWorkerManagerCapabilities + { + SupportsDynamicRegistration = false, + SupportsCronExpression = false + }; + public virtual Task AddAsync( string workerName, DynamicBackgroundWorkerSchedule schedule, diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs index 439e61de21..2fc674a06a 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs @@ -14,6 +14,12 @@ public class DefaultDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerMan { protected IServiceProvider ServiceProvider { get; } public ILogger Logger { get; set; } + public virtual DynamicBackgroundWorkerManagerCapabilities Capabilities { get; } = + new DynamicBackgroundWorkerManagerCapabilities + { + SupportsDynamicRegistration = true, + SupportsCronExpression = false + }; private readonly ConcurrentDictionary _dynamicWorkers; private readonly SemaphoreSlim _semaphore; @@ -39,11 +45,11 @@ public class DefaultDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerMan schedule.Validate(); - if (schedule.Period == null) + if (!schedule.CronExpression.IsNullOrWhiteSpace()) { throw new AbpException( - $"The default in-memory background worker manager does not support CronExpression without Period for dynamic worker '{workerName}'. " + - "Please set Period, or use a scheduler-backed provider (Hangfire, Quartz, TickerQ)."); + $"The default in-memory background worker manager does not support CronExpression for dynamic worker '{workerName}'. " + + "Please set Period, or use a scheduler-backed provider (Hangfire or Quartz)."); } await _semaphore.WaitAsync(cancellationToken); @@ -102,11 +108,11 @@ public class DefaultDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerMan schedule.Validate(); - if (schedule.Period == null) + if (!schedule.CronExpression.IsNullOrWhiteSpace()) { throw new AbpException( - $"The default in-memory background worker manager does not support CronExpression without Period for dynamic worker '{workerName}'. " + - "Please set Period, or use a scheduler-backed provider (Hangfire, Quartz, TickerQ)."); + $"The default in-memory background worker manager does not support CronExpression for dynamic worker '{workerName}'. " + + "Please set Period, or use a scheduler-backed provider (Hangfire or Quartz)."); } await _semaphore.WaitAsync(cancellationToken); diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs new file mode 100644 index 0000000000..ae8275e499 --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.BackgroundWorkers; + +public class DynamicBackgroundWorkerManagerCapabilities +{ + public bool SupportsDynamicRegistration { get; set; } = true; + + public bool SupportsCronExpression { get; set; } = true; +} diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs index 7e625e7c9c..3499bab63a 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs @@ -9,6 +9,11 @@ namespace Volo.Abp.BackgroundWorkers; /// public interface IDynamicBackgroundWorkerManager { + /// + /// Describes the scheduling and runtime-registration capabilities of the active dynamic worker provider. + /// + DynamicBackgroundWorkerManagerCapabilities Capabilities { get; } + /// /// Adds a dynamic worker by name, schedule and handler. /// If a worker with the same name already exists, it will be replaced. diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_Tests.cs index a61c99fdc1..32c28e182f 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManager_Tests.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Shouldly; +using Volo.Abp; using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundWorkers; using Xunit; @@ -20,6 +21,13 @@ public class DynamicBackgroundWorkerManager_Tests : BackgroundJobsTestBase _dynamicWorkerManager = GetRequiredService(); } + [Fact] + public void Should_Report_Provider_Capabilities() + { + _dynamicWorkerManager.Capabilities.SupportsDynamicRegistration.ShouldBeTrue(); + _dynamicWorkerManager.Capabilities.SupportsCronExpression.ShouldBeFalse(); + } + [Fact] public async Task Should_Register_Dynamic_Worker() { @@ -235,6 +243,25 @@ public class DynamicBackgroundWorkerManager_Tests : BackgroundJobsTestBase }); } + [Fact] + public async Task Should_Throw_When_CronExpression_Is_Set() + { + var workerName = "dynamic-worker-" + Guid.NewGuid(); + + await Assert.ThrowsAsync(async () => + { + await _dynamicWorkerManager.AddAsync( + workerName, + new DynamicBackgroundWorkerSchedule + { + Period = 1000, + CronExpression = "0 */5 * * * *" + }, + (_, _) => Task.CompletedTask + ); + }); + } + [Fact] public async Task Should_Continue_Running_After_Handler_Throws_Exception() {