From 29c38616f2d582937b50df8a1318ab86ee45eb7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SAL=C4=B0H=20=C3=96ZKARA?= Date: Fri, 8 May 2026 14:14:56 +0300 Subject: [PATCH 1/3] Expose dynamic worker scheduler capabilities --- .../HangfireDynamicBackgroundWorkerManager.cs | 2 ++ .../QuartzDynamicBackgroundWorkerManager.cs | 2 ++ .../TickerQDynamicBackgroundWorkerManager.cs | 7 +++++ .../DefaultDynamicBackgroundWorkerManager.cs | 18 ++++++++----- ...amicBackgroundWorkerManagerCapabilities.cs | 8 ++++++ .../IDynamicBackgroundWorkerManager.cs | 5 ++++ .../DynamicBackgroundWorkerManager_Tests.cs | 27 +++++++++++++++++++ 7 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs 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() { From 8054b26a31e512fca0b31b6630339749cb2bcc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SAL=C4=B0H=20=C3=96ZKARA?= Date: Mon, 11 May 2026 06:51:51 +0300 Subject: [PATCH 2/3] Use marker interfaces for dynamic worker capabilities --- .../HangfireDynamicBackgroundWorkerManager.cs | 8 +++++--- .../Quartz/QuartzDynamicBackgroundWorkerManager.cs | 8 +++++--- .../TickerQ/TickerQDynamicBackgroundWorkerManager.cs | 7 ------- .../DefaultDynamicBackgroundWorkerManager.cs | 11 ++++------- .../DynamicBackgroundWorkerManagerCapabilities.cs | 8 -------- .../IDynamicBackgroundWorkerManager.cs | 5 ----- .../Abp/BackgroundWorkers/ISupportsCronScheduling.cs | 8 ++++++++ .../BackgroundWorkers/ISupportsRuntimeRegistration.cs | 8 ++++++++ .../DynamicBackgroundWorkerManager_Tests.cs | 6 +++--- 9 files changed, 33 insertions(+), 36 deletions(-) delete mode 100644 framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs create mode 100644 framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsCronScheduling.cs create mode 100644 framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsRuntimeRegistration.cs 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 c3413096bc..d54e37c534 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 @@ -13,13 +13,15 @@ using Volo.Abp.Hangfire; namespace Volo.Abp.BackgroundWorkers.Hangfire; [Dependency(ReplaceServices = true)] -public class HangfireDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerManager, ISingletonDependency +public class HangfireDynamicBackgroundWorkerManager : + IDynamicBackgroundWorkerManager, + ISupportsRuntimeRegistration, + ISupportsCronScheduling, + ISingletonDependency { 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 f1c6736e4c..2f098d6ab4 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 @@ -10,15 +10,17 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundWorkers.Quartz; [Dependency(ReplaceServices = true)] -public class QuartzDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerManager, ISingletonDependency +public class QuartzDynamicBackgroundWorkerManager : + IDynamicBackgroundWorkerManager, + ISupportsRuntimeRegistration, + ISupportsCronScheduling, + ISingletonDependency { public const string DynamicWorkerNameKey = "AbpDynamicWorkerName"; 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 731bd3b1da..6976f49cb5 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,13 +7,6 @@ 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 2fc674a06a..6fdbb202d0 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs @@ -10,16 +10,13 @@ using Volo.Abp.Threading; namespace Volo.Abp.BackgroundWorkers; -public class DefaultDynamicBackgroundWorkerManager : IDynamicBackgroundWorkerManager, ISingletonDependency +public class DefaultDynamicBackgroundWorkerManager : + IDynamicBackgroundWorkerManager, + ISupportsRuntimeRegistration, + ISingletonDependency { 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; diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs deleted file mode 100644 index ae8275e499..0000000000 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DynamicBackgroundWorkerManagerCapabilities.cs +++ /dev/null @@ -1,8 +0,0 @@ -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 3499bab63a..7e625e7c9c 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs @@ -9,11 +9,6 @@ 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/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsCronScheduling.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsCronScheduling.cs new file mode 100644 index 0000000000..9160ef368a --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsCronScheduling.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.BackgroundWorkers; + +/// +/// Marks a dynamic background worker manager that supports cron-based scheduling. +/// +public interface ISupportsCronScheduling +{ +} diff --git a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsRuntimeRegistration.cs b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsRuntimeRegistration.cs new file mode 100644 index 0000000000..4f343113bf --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/ISupportsRuntimeRegistration.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.BackgroundWorkers; + +/// +/// Marks a dynamic background worker manager that supports registering workers at runtime. +/// +public interface ISupportsRuntimeRegistration +{ +} 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 32c28e182f..0614192662 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 @@ -22,10 +22,10 @@ public class DynamicBackgroundWorkerManager_Tests : BackgroundJobsTestBase } [Fact] - public void Should_Report_Provider_Capabilities() + public void Should_Report_Provider_Capabilities_Using_Marker_Interfaces() { - _dynamicWorkerManager.Capabilities.SupportsDynamicRegistration.ShouldBeTrue(); - _dynamicWorkerManager.Capabilities.SupportsCronExpression.ShouldBeFalse(); + (_dynamicWorkerManager is ISupportsRuntimeRegistration).ShouldBeTrue(); + (_dynamicWorkerManager is ISupportsCronScheduling).ShouldBeFalse(); } [Fact] From 44df9390a88991b0d92a258e4a00303a45f24604 Mon Sep 17 00:00:00 2001 From: maliming Date: Mon, 11 May 2026 13:05:43 +0800 Subject: [PATCH 3/3] Improve error messages for CronExpression in DefaultDynamicBackgroundWorkerManager and add test for exception on UpdateSchedule with CronExpression --- .../DefaultDynamicBackgroundWorkerManager.cs | 4 ++-- .../IDynamicBackgroundWorkerManager.cs | 6 +++++ .../DynamicBackgroundWorkerManager_Tests.cs | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) 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 6fdbb202d0..62dce443a8 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/DefaultDynamicBackgroundWorkerManager.cs @@ -46,7 +46,7 @@ public class DefaultDynamicBackgroundWorkerManager : { throw new AbpException( $"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)."); + "Please clear CronExpression and use Period-based scheduling, or use a scheduler-backed provider (Hangfire or Quartz)."); } await _semaphore.WaitAsync(cancellationToken); @@ -109,7 +109,7 @@ public class DefaultDynamicBackgroundWorkerManager : { throw new AbpException( $"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)."); + "Please clear CronExpression and use Period-based scheduling, or use a scheduler-backed provider (Hangfire or Quartz)."); } await _semaphore.WaitAsync(cancellationToken); 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..a897549249 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/IDynamicBackgroundWorkerManager.cs @@ -6,6 +6,12 @@ namespace Volo.Abp.BackgroundWorkers; /// /// Manages dynamic background workers that are registered at runtime /// without requiring a strongly-typed worker class. +/// +/// Implementations may differ in capabilities. Check +/// before calling / / , +/// and before passing +/// . +/// /// public interface IDynamicBackgroundWorkerManager { 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 0614192662..955b2104dd 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 @@ -262,6 +262,30 @@ public class DynamicBackgroundWorkerManager_Tests : BackgroundJobsTestBase }); } + [Fact] + public async Task Should_Throw_When_CronExpression_Is_Set_On_UpdateSchedule() + { + var workerName = "dynamic-worker-" + Guid.NewGuid(); + + await _dynamicWorkerManager.AddAsync( + workerName, + new DynamicBackgroundWorkerSchedule { Period = 1000 }, + (_, _) => Task.CompletedTask + ); + + await Assert.ThrowsAsync(async () => + { + await _dynamicWorkerManager.UpdateScheduleAsync( + workerName, + new DynamicBackgroundWorkerSchedule + { + Period = 1000, + CronExpression = "0 */5 * * * *" + } + ); + }); + } + [Fact] public async Task Should_Continue_Running_After_Handler_Throws_Exception() {