diff --git a/Directory.Packages.props b/Directory.Packages.props index 805da8ba7d..40fb9c08ef 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -183,10 +183,10 @@ - - - - + + + + diff --git a/docs/en/framework/infrastructure/background-jobs/tickerq.md b/docs/en/framework/infrastructure/background-jobs/tickerq.md index de7b3631f2..81dd021607 100644 --- a/docs/en/framework/infrastructure/background-jobs/tickerq.md +++ b/docs/en/framework/infrastructure/background-jobs/tickerq.md @@ -95,13 +95,13 @@ public class CleanupJobs public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) { var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService(); - abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) => + abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) => { var service = new CleanupJobs(); // Or get it from the serviceProvider var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken); var genericContext = new TickerFunctionContext(tickerFunctionContext, request); await service.CleanupLogsAsync(genericContext, cancellationToken); - }))); + }, TickerTaskPriority.Normal); abpTickerQFunctionProvider.RequestTypes.TryAdd(nameof(CleanupJobs), (typeof(string).FullName, typeof(string))); return Task.CompletedTask; } diff --git a/docs/en/framework/infrastructure/background-workers/tickerq.md b/docs/en/framework/infrastructure/background-workers/tickerq.md index d4ddde3cd9..4547b85b85 100644 --- a/docs/en/framework/infrastructure/background-workers/tickerq.md +++ b/docs/en/framework/infrastructure/background-workers/tickerq.md @@ -83,13 +83,13 @@ public class CleanupJobs public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) { var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService(); - abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) => + abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) => { var service = new CleanupJobs(); // Or get it from the serviceProvider var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken); var genericContext = new TickerFunctionContext(tickerFunctionContext, request); await service.CleanupLogsAsync(genericContext, cancellationToken); - }))); + }, TickerTaskPriority.Normal); abpTickerQFunctionProvider.RequestTypes.TryAdd(nameof(CleanupJobs), (typeof(string).FullName, typeof(string))); return Task.CompletedTask; } @@ -112,11 +112,11 @@ await cronTickerManager.AddAsync(new CronTickerEntity You can specify a cron expression instead of using `ICronTickerManager` to add a worker: ```csharp -abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) => +abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) => { var service = new CleanupJobs(); var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken); var genericContext = new TickerFunctionContext(tickerFunctionContext, request); await service.CleanupLogsAsync(genericContext, cancellationToken); -}))); +}, TickerTaskPriority.Normal); ``` diff --git a/docs/en/package-version-changes.md b/docs/en/package-version-changes.md index 8e1d492f29..67fce824d8 100644 --- a/docs/en/package-version-changes.md +++ b/docs/en/package-version-changes.md @@ -8,6 +8,10 @@ | Microsoft.IdentityModel.Protocols.OpenIdConnect | 8.14.0 | 8.16.0 | #25068 | | Microsoft.IdentityModel.Tokens | 8.14.0 | 8.16.0 | #25068 | | System.IdentityModel.Tokens.Jwt | 8.14.0 | 8.16.0 | #25068 | +| TickerQ | 10.1.1 | 10.2.0 | #25091 | +| TickerQ.Dashboard | 10.1.1 | 10.2.0 | #25091 | +| TickerQ.EntityFrameworkCore | 10.1.1 | 10.2.0 | #25091 | +| TickerQ.Utilities | 10.1.1 | 10.2.0 | #25091 | ## 10.3.0-preview diff --git a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs index 3d93fc68a1..157f0cc050 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTickerQModule.cs @@ -23,26 +23,14 @@ public class AbpBackgroundJobsTickerQModule : AbpModule { var abpBackgroundJobOptions = context.ServiceProvider.GetRequiredService>(); var abpBackgroundJobsTickerQOptions = context.ServiceProvider.GetRequiredService>(); - var tickerFunctionDelegates = new Dictionary(); - var requestTypes = new Dictionary(); + var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService(); foreach (var jobConfiguration in abpBackgroundJobOptions.Value.GetJobs()) { var genericMethod = GetTickerFunctionDelegateMethod.MakeGenericMethod(jobConfiguration.ArgsType); var tickerFunctionDelegate = (TickerFunctionDelegate)genericMethod.Invoke(null, [jobConfiguration.ArgsType])!; var config = abpBackgroundJobsTickerQOptions.Value.GetConfigurationOrNull(jobConfiguration.JobType); - tickerFunctionDelegates.TryAdd(jobConfiguration.JobName, (string.Empty, config?.Priority ?? TickerTaskPriority.Normal, tickerFunctionDelegate)); - requestTypes.TryAdd(jobConfiguration.JobName, (jobConfiguration.ArgsType.FullName, jobConfiguration.ArgsType)!); - } - - var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService(); - foreach (var functionDelegate in tickerFunctionDelegates) - { - abpTickerQFunctionProvider.Functions.TryAdd(functionDelegate.Key, functionDelegate.Value); - } - - foreach (var requestType in requestTypes) - { - abpTickerQFunctionProvider.RequestTypes.TryAdd(requestType.Key, requestType.Value); + abpTickerQFunctionProvider.AddFunction(jobConfiguration.JobName, tickerFunctionDelegate, config?.Priority ?? TickerTaskPriority.Normal, config?.MaxConcurrency ?? 0); + abpTickerQFunctionProvider.RequestTypes.TryAdd(jobConfiguration.JobName, (jobConfiguration.ArgsType.FullName, jobConfiguration.ArgsType)!); } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs index ecceaeb28a..1f2c6d32ac 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.TickerQ/Volo/Abp/BackgroundJobs/TickerQ/AbpBackgroundJobsTimeTickerConfiguration.cs @@ -10,5 +10,7 @@ public class AbpBackgroundJobsTimeTickerConfiguration public TickerTaskPriority? Priority { get; set; } + public int? MaxConcurrency { get; set; } + public RunCondition? RunCondition { get; set; } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs index 0e8ed89a14..662c05a58a 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpBackgroundWorkersCronTickerConfiguration.cs @@ -9,4 +9,6 @@ public class AbpBackgroundWorkersCronTickerConfiguration public int[]? RetryIntervals { get; set; } public TickerTaskPriority? Priority { get; set; } + + public int? MaxConcurrency { get; set; } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs index 922cad294d..cc6c847197 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.TickerQ/Volo/Abp/BackgroundWorkers/TickerQ/AbpTickerQBackgroundWorkerManager.cs @@ -53,11 +53,11 @@ public class AbpTickerQBackgroundWorkerManager : BackgroundWorkerManager, ISingl var name = BackgroundWorkerNameAttribute.GetNameOrNull(worker.GetType()) ?? worker.GetType().FullName; var config = Options.GetConfigurationOrNull(ProxyHelper.GetUnProxiedType(worker)); - AbpTickerQFunctionProvider.Functions.TryAdd(name!, (string.Empty, config?.Priority ?? TickerTaskPriority.LongRunning, async (tickerQCancellationToken, serviceProvider, tickerFunctionContext) => + AbpTickerQFunctionProvider.AddFunction(name!, async (tickerQCancellationToken, serviceProvider, tickerFunctionContext) => { var workerInvoker = new AbpTickerQPeriodicBackgroundWorkerInvoker(worker, serviceProvider); await workerInvoker.DoWorkAsync(tickerFunctionContext, tickerQCancellationToken); - })); + }, config?.Priority ?? TickerTaskPriority.LongRunning, config?.MaxConcurrency ?? 0); AbpTickerQBackgroundWorkersProvider.BackgroundWorkers.Add(name!, new AbpTickerQCronBackgroundWorker { diff --git a/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs b/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs index b92888e533..b6b05e7787 100644 --- a/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs +++ b/framework/src/Volo.Abp.TickerQ/Volo/Abp/TickerQ/AbpTickerQFunctionProvider.cs @@ -8,13 +8,33 @@ namespace Volo.Abp.TickerQ; public class AbpTickerQFunctionProvider : ISingletonDependency { - public Dictionary Functions { get;} + public Dictionary Functions { get; } - public Dictionary RequestTypes { get; } + public Dictionary RequestTypes { get; } public AbpTickerQFunctionProvider() { - Functions = new Dictionary(); + Functions = new Dictionary(); RequestTypes = new Dictionary(); } + + public void AddFunction( + string name, + TickerFunctionDelegate function, + TickerTaskPriority priority = TickerTaskPriority.Normal, + int maxConcurrency = 0) + { + Check.NotNullOrWhiteSpace(name, nameof(name)); + Check.NotNull(function, nameof(function)); + + if (maxConcurrency < 0) + { + throw new ArgumentException("maxConcurrency must be greater than or equal to 0.", nameof(maxConcurrency)); + } + + if (!Functions.TryAdd(name, (string.Empty, priority, function, maxConcurrency))) + { + throw new AbpException($"A function with the name '{name}' is already registered."); + } + } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs index de3ef3c05d..29027a2a75 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.TickerQ/DemoAppTickerQModule.cs @@ -77,13 +77,13 @@ public class DemoAppTickerQModule : AbpModule public override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context) { var abpTickerQFunctionProvider = context.ServiceProvider.GetRequiredService(); - abpTickerQFunctionProvider.Functions.TryAdd(nameof(CleanupJobs), (string.Empty, TickerTaskPriority.Normal, new TickerFunctionDelegate(async (cancellationToken, serviceProvider, tickerFunctionContext) => + abpTickerQFunctionProvider.AddFunction(nameof(CleanupJobs), async (cancellationToken, serviceProvider, tickerFunctionContext) => { var service = new CleanupJobs(); var request = await TickerRequestProvider.GetRequestAsync(tickerFunctionContext, cancellationToken); var genericContext = new TickerFunctionContext(tickerFunctionContext, request); await service.CleanupLogsAsync(genericContext, cancellationToken); - }))); + }, TickerTaskPriority.Normal); abpTickerQFunctionProvider.RequestTypes.TryAdd(nameof(CleanupJobs), (typeof(string).FullName, typeof(string))); return Task.CompletedTask; }