From dcd091adfbf94b3bcc6ad1ae9e7b75f47f22523d Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Sun, 1 Jan 2023 16:48:40 +0300 Subject: [PATCH 1/8] CancellationToken parameter added for background jobs --- .../Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs | 5 +++-- .../Volo/Abp/BackgroundJobs/BackgroundJob.cs | 3 ++- .../Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs | 4 ++-- .../Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs | 6 ++++-- .../Volo/Abp/BackgroundJobs/IBackgroundJob.cs | 7 +++++-- .../Volo/Abp/BackgroundJobs/JobExecutionContext.cs | 10 +++++++++- .../Hangfire/HangfireBackgroundJobManager.cs | 8 ++++---- .../Hangfire/HangfireJobExecutionAdapter.cs | 9 +++++---- .../BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs | 2 +- .../Volo/Abp/Emailing/BackgroundEmailSendingJob.cs | 3 ++- .../Volo/Abp/BackgroundJobs/MyAsyncJob.cs | 3 ++- .../Volo/Abp/BackgroundJobs/MyJob.cs | 3 ++- 12 files changed, 41 insertions(+), 22 deletions(-) diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs index 4cf298f712..5e124191aa 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -15,5 +16,5 @@ public abstract class AsyncBackgroundJob : IAsyncBackgroundJob Logger = NullLogger>.Instance; } - public abstract Task ExecuteAsync(TArgs args); + public abstract Task ExecuteAsync(TArgs args, CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs index 57beeb77b5..a05409caa0 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs @@ -1,3 +1,4 @@ +using System.Threading; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -14,5 +15,5 @@ public abstract class BackgroundJob : IBackgroundJob Logger = NullLogger>.Instance; } - public abstract void Execute(TArgs args); + public abstract void Execute(TArgs args, CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs index 7a6f54fbd7..c43fcabd0f 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs @@ -48,11 +48,11 @@ public class BackgroundJobExecuter : IBackgroundJobExecuter, ITransientDependenc { if (jobExecuteMethod.Name == nameof(IAsyncBackgroundJob.ExecuteAsync)) { - await ((Task)jobExecuteMethod.Invoke(job, new[] { context.JobArgs })); + await ((Task)jobExecuteMethod.Invoke(job, new[] { context.JobArgs, context.CancellationToken })); } else { - jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); + jobExecuteMethod.Invoke(job, new[] { context.JobArgs, context.CancellationToken }); } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs index dc39b1bd0f..b7a57f04ce 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; namespace Volo.Abp.BackgroundJobs; @@ -11,5 +12,6 @@ public interface IAsyncBackgroundJob /// Executes the job with the . /// /// Job arguments. - Task ExecuteAsync(TArgs args); + /// A to observe while waiting for the task to complete. + Task ExecuteAsync(TArgs args, CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs index 140db1e72a..7bcfebe861 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs @@ -1,4 +1,6 @@ -namespace Volo.Abp.BackgroundJobs; +using System.Threading; + +namespace Volo.Abp.BackgroundJobs; /// /// Defines interface of a background job. @@ -9,5 +11,6 @@ public interface IBackgroundJob /// Executes the job with the . /// /// Job arguments. - void Execute(TArgs args); + /// A to observe while waiting for the task to complete. + void Execute(TArgs args, CancellationToken cancellationToken = default); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs index a5de60d298..ae7e098070 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/JobExecutionContext.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundJobs; @@ -11,10 +12,17 @@ public class JobExecutionContext : IServiceProviderAccessor public object JobArgs { get; } - public JobExecutionContext(IServiceProvider serviceProvider, Type jobType, object jobArgs) + public CancellationToken CancellationToken { get; } + + public JobExecutionContext( + IServiceProvider serviceProvider, + Type jobType, + object jobArgs, + CancellationToken cancellationToken = default) { ServiceProvider = serviceProvider; JobType = jobType; JobArgs = jobArgs; + CancellationToken = cancellationToken; } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs index 2583ada9fc..a94426adad 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs @@ -12,22 +12,22 @@ namespace Volo.Abp.BackgroundJobs.Hangfire; public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDependency { protected AbpBackgroundJobOptions Options { get; } - + public HangfireBackgroundJobManager(IOptions options) { Options = options.Value; } - + public virtual Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) { return Task.FromResult(delay.HasValue ? BackgroundJob.Schedule>( - adapter => adapter.ExecuteAsync(GetQueueName(typeof(TArgs)),args), + adapter => adapter.ExecuteAsync(GetQueueName(typeof(TArgs)), args, default), delay.Value ) : BackgroundJob.Enqueue>( - adapter => adapter.ExecuteAsync(GetQueueName(typeof(TArgs)) ,args) + adapter => adapter.ExecuteAsync(GetQueueName(typeof(TArgs)), args, default) )); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs index 7ba0cd7db4..58d2863618 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Threading; +using System.Threading.Tasks; using Hangfire; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -21,8 +22,8 @@ public class HangfireJobExecutionAdapter Options = options.Value; } - [Queue("{0}")] - public async Task ExecuteAsync(string queue, TArgs args) + [Queue("{0}")] + public async Task ExecuteAsync(string queue, TArgs args, CancellationToken cancellationToken = default) { if (!Options.IsJobExecutionEnabled) { @@ -38,7 +39,7 @@ public class HangfireJobExecutionAdapter using (var scope = ServiceScopeFactory.CreateScope()) { var jobType = Options.GetJob(typeof(TArgs)).JobType; - var context = new JobExecutionContext(scope.ServiceProvider, jobType, args); + var context = new JobExecutionContext(scope.ServiceProvider, jobType, args, cancellationToken: cancellationToken); await JobExecuter.ExecuteAsync(context); } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs b/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs index 3127cc5910..588e844153 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs @@ -40,7 +40,7 @@ public class QuartzJobExecutionAdapter : IJob { var args = JsonSerializer.Deserialize(context.JobDetail.JobDataMap.GetString(nameof(TArgs))); var jobType = Options.GetJob(typeof(TArgs)).JobType; - var jobContext = new JobExecutionContext(scope.ServiceProvider, jobType, args); + var jobContext = new JobExecutionContext(scope.ServiceProvider, jobType, args, cancellationToken: context.CancellationToken); try { await JobExecuter.ExecuteAsync(jobContext); diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs index 881a6437d9..70009d6ffc 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.BackgroundJobs; using Volo.Abp.DependencyInjection; @@ -14,7 +15,7 @@ public class BackgroundEmailSendingJob : AsyncBackgroundJob, ISingletonDependen _currentTenant = currentTenant; } - public override Task ExecuteAsync(MyAsyncJobArgs args) + public override Task ExecuteAsync(MyAsyncJobArgs args, CancellationToken cancellationToken = default) { ExecutedValues.Add(args.Value); TenantId = _currentTenant.Id; diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs index 3b01ec05d1..ab1e78c942 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; @@ -18,7 +19,7 @@ public class MyJob : BackgroundJob, ISingletonDependency _currentTenant = currentTenant; } - public override void Execute(MyJobArgs args) + public override void Execute(MyJobArgs args, CancellationToken cancellationToken = default) { ExecutedValues.Add(args.Value); TenantId = _currentTenant.Id; From 638c113a1f1340862fa7d90243c98b9088b9ab3a Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Mon, 2 Jan 2023 09:28:14 +0300 Subject: [PATCH 2/8] CancellationToken parameter added for background jobs demo app --- .../Jobs/WriteToConsoleGreenJob.cs | 3 ++- .../Jobs/WriteToConsoleYellowJob.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs index e065e409e5..9163ca62c2 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs @@ -1,11 +1,12 @@ using System; +using System.Threading; using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs { public class WriteToConsoleGreenJob : BackgroundJob, ITransientDependency { - public override void Execute(WriteToConsoleGreenJobArgs args) + public override void Execute(WriteToConsoleGreenJobArgs args, CancellationToken cancellationToken = default) { if (RandomHelper.GetRandom(0, 100) < 70) { diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs index a610b6e75a..7daedb68c4 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs @@ -1,11 +1,12 @@ using System; +using System.Threading; using Volo.Abp.DependencyInjection; namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs { public class WriteToConsoleYellowJob : BackgroundJob, ITransientDependency { - public override void Execute(WriteToConsoleYellowJobArgs args) + public override void Execute(WriteToConsoleYellowJobArgs args, CancellationToken cancellationToken = default) { if (RandomHelper.GetRandom(0, 100) < 70) { From 1c8ea86c3525dc061d3ddb8cae5f80e21256b5ba Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Mon, 2 Jan 2023 13:38:13 +0300 Subject: [PATCH 3/8] Background job cancellation sample added --- .../Program.cs | 24 +++++++++-- .../Program.cs | 19 +++++++++ .../Jobs/LongRunningJob.cs | 41 +++++++++++++++++++ .../Jobs/LongRunningJobArgs.cs | 8 ++++ 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs create mode 100644 modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJobArgs.cs diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs index 5f2c23ceb4..c2ed43f336 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs @@ -1,4 +1,9 @@ using System; +using System.Threading; +using Hangfire; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs.DemoApp.HangFire; @@ -7,12 +12,13 @@ class Program static void Main(string[] args) { using (var application = AbpApplicationFactory.Create(options => - { - options.UseAutofac(); - })) + { + options.UseAutofac(); + })) { application.Initialize(); + CancelableBackgroundJob(application.ServiceProvider); Console.WriteLine("Started: " + typeof(Program).Namespace); Console.WriteLine("Press ENTER to stop the application..!"); Console.ReadLine(); @@ -20,4 +26,16 @@ class Program application.Shutdown(); } } + + private static void CancelableBackgroundJob(IServiceProvider serviceProvider) + { + AsyncHelper.RunSync(async () => + { + var backgroundJobManager = serviceProvider.GetRequiredService(); + var jobId = await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-1" }); + await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-2" }); + Thread.Sleep(1000); + BackgroundJob.Delete(jobId); + }); + } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs index 1ececcd621..17cd5a7609 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs @@ -1,4 +1,9 @@ using System; +using System.Threading; +using Microsoft.Extensions.DependencyInjection; +using Quartz; +using Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs.DemoApp.Quartz; @@ -13,6 +18,7 @@ class Program { application.Initialize(); + CancelableBackgroundJob(application.ServiceProvider); Console.WriteLine("Started: " + typeof(Program).Namespace); Console.WriteLine("Press ENTER to stop the application..!"); Console.ReadLine(); @@ -20,4 +26,17 @@ class Program application.Shutdown(); } } + + private static void CancelableBackgroundJob(IServiceProvider serviceProvider) + { + AsyncHelper.RunSync(async () => + { + var backgroundJobManager = serviceProvider.GetRequiredService(); + var jobId = await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-1" }); + await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-2" }); + Thread.Sleep(1000); + var scheduler = serviceProvider.GetRequiredService(); + await scheduler.Interrupt(new JobKey(jobId.Split('.')[1],jobId.Split('.')[0])); + }); + } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs new file mode 100644 index 0000000000..73393bdcc2 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs +{ + public class LongRunningJob : BackgroundJob, ITransientDependency + { + public override void Execute(LongRunningJobArgs args, CancellationToken cancellationToken = default) + { + lock (Console.Out) + { + var oldColor = Console.ForegroundColor; + try + { + Console.WriteLine($"Long running {args.Value} start: {DateTime.Now}"); + + for (var i = 1; i <= 10; i++) + { + cancellationToken.ThrowIfCancellationRequested(); + + Thread.Sleep(1000); + Console.WriteLine($"{args.Value} step-{i} done: {DateTime.Now}"); + } + + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine($"Long running {args.Value} completed: {DateTime.Now}"); + } + catch (OperationCanceledException) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"Long running {args.Value} cancelled!!!"); + } + finally + { + Console.ForegroundColor = oldColor; + } + } + } + } +} \ No newline at end of file diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJobArgs.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJobArgs.cs new file mode 100644 index 0000000000..fabba0fa57 --- /dev/null +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJobArgs.cs @@ -0,0 +1,8 @@ +namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs +{ + [BackgroundJobName("LongJob")] + public class LongRunningJobArgs + { + public string Value { get; set; } + } +} \ No newline at end of file From e84367ceb32e792c8d0d04ef79b96406ab2cde20 Mon Sep 17 00:00:00 2001 From: maliming Date: Wed, 11 Jan 2023 11:42:42 +0800 Subject: [PATCH 4/8] Add unit test and update DemoApp. --- .../Abp/BackgroundJobs/BackgroundJobWorker.cs | 3 +- .../BackgroundJobExecuter_Tests.cs | 45 ++++++++++++++++++- .../Volo/Abp/BackgroundJobs/MyAsyncJob.cs | 11 ++++- .../Volo/Abp/BackgroundJobs/MyJob.cs | 11 ++++- .../Program.cs | 27 ++++++----- .../Program.cs | 31 +++++++------ .../Program.cs | 9 ++-- .../DemoAppModule.cs | 11 +++-- .../Program.cs | 10 ++--- 9 files changed, 108 insertions(+), 50 deletions(-) diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs index 8de0a5ff6e..4aeaf59885 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs @@ -68,7 +68,8 @@ public class BackgroundJobWorker : AsyncPeriodicBackgroundWorkerBase, IBackgroun var context = new JobExecutionContext( workerContext.ServiceProvider, jobConfiguration.JobType, - jobArgs); + jobArgs, + workerContext.CancellationToken); try { diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs index 42fe0da502..491bae2967 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using Shouldly; using Xunit; @@ -59,7 +60,7 @@ public class BackgroundJobExecuter_Tests : BackgroundJobsTestBase jobObject.ExecutedValues.ShouldContain("42"); } - + [Fact] public async Task Should_Change_TenantId_If_EventData_Is_MultiTenant() { @@ -77,7 +78,7 @@ public class BackgroundJobExecuter_Tests : BackgroundJobsTestBase new MyJobArgs("42", tenantId) ) ); - + await _backgroundJobExecuter.ExecuteAsync( new JobExecutionContext( ServiceProvider, @@ -91,4 +92,44 @@ public class BackgroundJobExecuter_Tests : BackgroundJobsTestBase jobObject.TenantId.ShouldBe(tenantId); asyncJobObject.TenantId.ShouldBe(tenantId); } + + [Fact] + public async Task Should_Cancel_Job() + { + //Arrange + var cts = new CancellationTokenSource(); + cts.Cancel(); + + var jobObject = GetRequiredService(); + jobObject.ExecutedValues.ShouldBeEmpty(); + + //Act + await _backgroundJobExecuter.ExecuteAsync( + new JobExecutionContext( + ServiceProvider, + typeof(MyJob), + new MyJobArgs("42"), + cts.Token + ) + ); + + //Assert + jobObject.Canceled.ShouldBeTrue(); + + //Arrange + var asyncJobObject = GetRequiredService(); + asyncJobObject.ExecutedValues.ShouldBeEmpty(); + + //Act + await _backgroundJobExecuter.ExecuteAsync( + new JobExecutionContext( + ServiceProvider, + typeof(MyAsyncJob), + new MyAsyncJobArgs("42") + ) + ); + + //Assert + jobObject.Canceled.ShouldBeTrue(); + } } diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs index 1480403a2a..5774902a4f 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs @@ -10,11 +10,13 @@ namespace Volo.Abp.BackgroundJobs; public class MyAsyncJob : AsyncBackgroundJob, ISingletonDependency { public List ExecutedValues { get; } = new List(); - + public Guid? TenantId { get; set; } - + private readonly ICurrentTenant _currentTenant; + public bool Canceled { get; set; } + public MyAsyncJob(ICurrentTenant currentTenant) { _currentTenant = currentTenant; @@ -22,6 +24,11 @@ public class MyAsyncJob : AsyncBackgroundJob, ISingletonDependen public override Task ExecuteAsync(MyAsyncJobArgs args, CancellationToken cancellationToken = default) { + if (cancellationToken.IsCancellationRequested) + { + Canceled = true; + } + ExecutedValues.Add(args.Value); TenantId = _currentTenant.Id; return Task.CompletedTask; diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs index ab1e78c942..a80e4f02b4 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs @@ -9,11 +9,13 @@ namespace Volo.Abp.BackgroundJobs; public class MyJob : BackgroundJob, ISingletonDependency { public List ExecutedValues { get; } = new List(); - + public Guid? TenantId { get; set; } private readonly ICurrentTenant _currentTenant; - + + public bool Canceled { get; set; } + public MyJob(ICurrentTenant currentTenant) { _currentTenant = currentTenant; @@ -21,6 +23,11 @@ public class MyJob : BackgroundJob, ISingletonDependency public override void Execute(MyJobArgs args, CancellationToken cancellationToken = default) { + if (cancellationToken.IsCancellationRequested) + { + Canceled = true; + } + ExecutedValues.Add(args.Value); TenantId = _currentTenant.Id; } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs index c2ed43f336..244063d37f 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Program.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using System.Threading.Tasks; using Hangfire; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs; @@ -9,33 +10,31 @@ namespace Volo.Abp.BackgroundJobs.DemoApp.HangFire; class Program { - static void Main(string[] args) + async static Task Main(string[] args) { - using (var application = AbpApplicationFactory.Create(options => + using (var application = await AbpApplicationFactory.CreateAsync(options => { options.UseAutofac(); })) { - application.Initialize(); + await application.InitializeAsync(); + + await CancelableBackgroundJobAsync(application.ServiceProvider); - CancelableBackgroundJob(application.ServiceProvider); Console.WriteLine("Started: " + typeof(Program).Namespace); Console.WriteLine("Press ENTER to stop the application..!"); Console.ReadLine(); - application.Shutdown(); + await application.ShutdownAsync(); } } - private static void CancelableBackgroundJob(IServiceProvider serviceProvider) + private async static Task CancelableBackgroundJobAsync(IServiceProvider serviceProvider) { - AsyncHelper.RunSync(async () => - { - var backgroundJobManager = serviceProvider.GetRequiredService(); - var jobId = await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-1" }); - await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-2" }); - Thread.Sleep(1000); - BackgroundJob.Delete(jobId); - }); + var backgroundJobManager = serviceProvider.GetRequiredService(); + var jobId = await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-1" }); + await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-2" }); + Thread.Sleep(1000); + BackgroundJob.Delete(jobId); } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs index 17cd5a7609..eebe5fa279 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Quartz/Program.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Quartz; using Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs; @@ -9,34 +10,32 @@ namespace Volo.Abp.BackgroundJobs.DemoApp.Quartz; class Program { - static void Main(string[] args) + async static Task Main(string[] args) { - using (var application = AbpApplicationFactory.Create(options => + using (var application = await AbpApplicationFactory.CreateAsync(options => { options.UseAutofac(); })) { - application.Initialize(); + await application.InitializeAsync(); + + await CancelableBackgroundJobAsync(application.ServiceProvider); - CancelableBackgroundJob(application.ServiceProvider); Console.WriteLine("Started: " + typeof(Program).Namespace); Console.WriteLine("Press ENTER to stop the application..!"); Console.ReadLine(); - application.Shutdown(); + await application.ShutdownAsync(); } } - - private static void CancelableBackgroundJob(IServiceProvider serviceProvider) + + private async static Task CancelableBackgroundJobAsync(IServiceProvider serviceProvider) { - AsyncHelper.RunSync(async () => - { - var backgroundJobManager = serviceProvider.GetRequiredService(); - var jobId = await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-1" }); - await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-2" }); - Thread.Sleep(1000); - var scheduler = serviceProvider.GetRequiredService(); - await scheduler.Interrupt(new JobKey(jobId.Split('.')[1],jobId.Split('.')[0])); - }); + var backgroundJobManager = serviceProvider.GetRequiredService(); + var jobId = await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs {Value = "test-1"}); + await backgroundJobManager.EnqueueAsync(new LongRunningJobArgs { Value = "test-2" }); + Thread.Sleep(1000); + var scheduler = serviceProvider.GetRequiredService(); + await scheduler.Interrupt(new JobKey(jobId.Split('.')[1],jobId.Split('.')[0])); } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Program.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Program.cs index 5d04169c15..a07a0498f9 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Program.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.RabbitMq/Program.cs @@ -1,23 +1,24 @@ using System; +using System.Threading.Tasks; namespace Volo.Abp.BackgroundJobs.DemoApp.RabbitMq; class Program { - static void Main(string[] args) + async static Task Main(string[] args) { - using (var application = AbpApplicationFactory.Create(options => + using (var application = await AbpApplicationFactory.CreateAsync(options => { options.UseAutofac(); })) { - application.Initialize(); + await application.InitializeAsync(); Console.WriteLine("Started: " + typeof(Program).Namespace); Console.WriteLine("Press ENTER to stop the application..!"); Console.ReadLine(); - application.Shutdown(); + await application.ShutdownAsync(); } } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs index a909fb476e..976705b07d 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/DemoAppModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Autofac; +using System.Threading.Tasks; +using Volo.Abp.Autofac; using Volo.Abp.BackgroundJobs.DemoApp.Shared; using Volo.Abp.BackgroundJobs.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -27,19 +28,21 @@ public class DemoAppModule : AbpModule Configure(options => { - //Configure for fast running - options.JobPollPeriod = 1000; + //Configure for fast running + options.JobPollPeriod = 1000; options.DefaultFirstWaitDuration = 1; options.DefaultWaitFactor = 1; }); } - public override void OnApplicationInitialization(ApplicationInitializationContext context) + public override Task OnApplicationInitializationAsync(ApplicationInitializationContext context) { //TODO: Configure console logging //context // .ServiceProvider // .GetRequiredService() // .AddConsole(LogLevel.Debug); + + return Task.CompletedTask; } } diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Program.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Program.cs index f895e7adbb..f8fa05863d 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Program.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp/Program.cs @@ -1,23 +1,23 @@ using System; - +using System.Threading.Tasks; namespace Volo.Abp.BackgroundJobs.DemoApp; class Program { - static void Main(string[] args) + async static Task Main(string[] args) { - using (var application = AbpApplicationFactory.Create(options => + using (var application = await AbpApplicationFactory.CreateAsync(options => { options.UseAutofac(); })) { - application.Initialize(); + await application.InitializeAsync(); Console.WriteLine("Started: " + typeof(Program).Namespace); Console.WriteLine("Press ENTER to stop the application..!"); Console.ReadLine(); - application.Shutdown(); + await application.ShutdownAsync(); } } } From 69bbb7523f394a6019c806d702457af2445374c4 Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Wed, 1 Feb 2023 15:35:37 +0300 Subject: [PATCH 5/8] Background job cancellation token scope changed as ambient context --- .../Abp/BackgroundJobs/AsyncBackgroundJob.cs | 4 ++-- .../Volo/Abp/BackgroundJobs/BackgroundJob.cs | 4 ++-- .../BackgroundJobs/BackgroundJobExecuter.cs | 19 +++++++++++++------ .../Abp/BackgroundJobs/IAsyncBackgroundJob.cs | 3 +-- .../Volo/Abp/BackgroundJobs/IBackgroundJob.cs | 3 +-- .../Abp/Emailing/BackgroundEmailSendingJob.cs | 2 +- .../BackgroundJobExecuter_Tests.cs | 8 ++++++-- .../Volo/Abp/BackgroundJobs/MyAsyncJob.cs | 11 ++++++++--- .../Volo/Abp/BackgroundJobs/MyJob.cs | 11 ++++++++--- 9 files changed, 42 insertions(+), 23 deletions(-) diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs index 5e124191aa..aa6cad070a 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AsyncBackgroundJob.cs @@ -7,7 +7,7 @@ namespace Volo.Abp.BackgroundJobs; public abstract class AsyncBackgroundJob : IAsyncBackgroundJob { - //TODO: Add UOW, Localization and other useful properties..? + //TODO: Add UOW, Localization, CancellationTokenProvider and other useful properties..? public ILogger> Logger { get; set; } @@ -16,5 +16,5 @@ public abstract class AsyncBackgroundJob : IAsyncBackgroundJob Logger = NullLogger>.Instance; } - public abstract Task ExecuteAsync(TArgs args, CancellationToken cancellationToken = default); + public abstract Task ExecuteAsync(TArgs args); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs index a05409caa0..b1770942fe 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJob.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.BackgroundJobs; public abstract class BackgroundJob : IBackgroundJob { - //TODO: Add UOW, Localization and other useful properties..? + //TODO: Add UOW, Localization, CancellationTokenProvider and other useful properties..? public ILogger> Logger { get; set; } @@ -15,5 +15,5 @@ public abstract class BackgroundJob : IBackgroundJob Logger = NullLogger>.Instance; } - public abstract void Execute(TArgs args, CancellationToken cancellationToken = default); + public abstract void Execute(TArgs args); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs index c43fcabd0f..7798a8d9a6 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.DependencyInjection; using Volo.Abp.ExceptionHandling; using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs; @@ -46,13 +47,19 @@ public class BackgroundJobExecuter : IBackgroundJobExecuter, ITransientDependenc { using(CurrentTenant.Change(GetJobArgsTenantId(context.JobArgs))) { - if (jobExecuteMethod.Name == nameof(IAsyncBackgroundJob.ExecuteAsync)) - { - await ((Task)jobExecuteMethod.Invoke(job, new[] { context.JobArgs, context.CancellationToken })); - } - else + var cancellationTokenProvider = + context.ServiceProvider.GetRequiredService(); + + using (cancellationTokenProvider.Use(context.CancellationToken)) { - jobExecuteMethod.Invoke(job, new[] { context.JobArgs, context.CancellationToken }); + if (jobExecuteMethod.Name == nameof(IAsyncBackgroundJob.ExecuteAsync)) + { + await ((Task)jobExecuteMethod.Invoke(job, new[] { context.JobArgs })); + } + else + { + jobExecuteMethod.Invoke(job, new[] { context.JobArgs }); + } } } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs index b7a57f04ce..022067d3ed 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs @@ -12,6 +12,5 @@ public interface IAsyncBackgroundJob /// Executes the job with the . /// /// Job arguments. - /// A to observe while waiting for the task to complete. - Task ExecuteAsync(TArgs args, CancellationToken cancellationToken = default); + Task ExecuteAsync(TArgs args); } diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs index 7bcfebe861..8c8c17ca93 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs +++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs @@ -11,6 +11,5 @@ public interface IBackgroundJob /// Executes the job with the . /// /// Job arguments. - /// A to observe while waiting for the task to complete. - void Execute(TArgs args, CancellationToken cancellationToken = default); + void Execute(TArgs args); } diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs index 70009d6ffc..9a70469df8 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/BackgroundEmailSendingJob.cs @@ -15,7 +15,7 @@ public class BackgroundEmailSendingJob : AsyncBackgroundJob(); asyncJobObject.ExecutedValues.ShouldBeEmpty(); @@ -125,11 +128,12 @@ public class BackgroundJobExecuter_Tests : BackgroundJobsTestBase new JobExecutionContext( ServiceProvider, typeof(MyAsyncJob), - new MyAsyncJobArgs("42") + new MyAsyncJobArgs("42"), + asyncCts.Token ) ); //Assert - jobObject.Canceled.ShouldBeTrue(); + asyncJobObject.Canceled.ShouldBeTrue(); } } diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs index 5774902a4f..d738b36130 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyAsyncJob.cs @@ -4,6 +4,7 @@ using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs; @@ -14,17 +15,21 @@ public class MyAsyncJob : AsyncBackgroundJob, ISingletonDependen public Guid? TenantId { get; set; } private readonly ICurrentTenant _currentTenant; + private readonly ICancellationTokenProvider _cancellationTokenProvider; public bool Canceled { get; set; } - public MyAsyncJob(ICurrentTenant currentTenant) + public MyAsyncJob( + ICurrentTenant currentTenant, + ICancellationTokenProvider cancellationTokenProvider) { _currentTenant = currentTenant; + _cancellationTokenProvider = cancellationTokenProvider; } - public override Task ExecuteAsync(MyAsyncJobArgs args, CancellationToken cancellationToken = default) + public override Task ExecuteAsync(MyAsyncJobArgs args) { - if (cancellationToken.IsCancellationRequested) + if (_cancellationTokenProvider.Token.IsCancellationRequested) { Canceled = true; } diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs index a80e4f02b4..1f9658162d 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading; using Volo.Abp.DependencyInjection; using Volo.Abp.MultiTenancy; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs; @@ -13,17 +14,21 @@ public class MyJob : BackgroundJob, ISingletonDependency public Guid? TenantId { get; set; } private readonly ICurrentTenant _currentTenant; + private readonly ICancellationTokenProvider _cancellationTokenProvider; public bool Canceled { get; set; } - public MyJob(ICurrentTenant currentTenant) + public MyJob( + ICurrentTenant currentTenant, + ICancellationTokenProvider cancellationTokenProvider) { _currentTenant = currentTenant; + _cancellationTokenProvider = cancellationTokenProvider; } - public override void Execute(MyJobArgs args, CancellationToken cancellationToken = default) + public override void Execute(MyJobArgs args) { - if (cancellationToken.IsCancellationRequested) + if (_cancellationTokenProvider.Token.IsCancellationRequested) { Canceled = true; } From 97f852f454ce8db010bc191928855e4cfa38adfe Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Wed, 1 Feb 2023 15:38:19 +0300 Subject: [PATCH 6/8] Update DemoApp --- .../Jobs/LongRunningJob.cs | 12 ++++++++++-- .../Jobs/WriteToConsoleGreenJob.cs | 2 +- .../Jobs/WriteToConsoleYellowJob.cs | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs index 73393bdcc2..9a57331fff 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/LongRunningJob.cs @@ -1,12 +1,20 @@ using System; using System.Threading; using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs { public class LongRunningJob : BackgroundJob, ITransientDependency { - public override void Execute(LongRunningJobArgs args, CancellationToken cancellationToken = default) + private readonly ICancellationTokenProvider _cancellationTokenProvider; + + public LongRunningJob(ICancellationTokenProvider cancellationTokenProvider) + { + _cancellationTokenProvider = cancellationTokenProvider; + } + + public override void Execute(LongRunningJobArgs args) { lock (Console.Out) { @@ -17,7 +25,7 @@ namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs for (var i = 1; i <= 10; i++) { - cancellationToken.ThrowIfCancellationRequested(); + _cancellationTokenProvider.Token.ThrowIfCancellationRequested(); Thread.Sleep(1000); Console.WriteLine($"{args.Value} step-{i} done: {DateTime.Now}"); diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs index 9163ca62c2..5e5c00a97d 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleGreenJob.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs { public class WriteToConsoleGreenJob : BackgroundJob, ITransientDependency { - public override void Execute(WriteToConsoleGreenJobArgs args, CancellationToken cancellationToken = default) + public override void Execute(WriteToConsoleGreenJobArgs args) { if (RandomHelper.GetRandom(0, 100) < 70) { diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs index 7daedb68c4..dbeae26552 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.Shared/Jobs/WriteToConsoleYellowJob.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.BackgroundJobs.DemoApp.Shared.Jobs { public class WriteToConsoleYellowJob : BackgroundJob, ITransientDependency { - public override void Execute(WriteToConsoleYellowJobArgs args, CancellationToken cancellationToken = default) + public override void Execute(WriteToConsoleYellowJobArgs args) { if (RandomHelper.GetRandom(0, 100) < 70) { From 94280674cfaa0a2d20fde96aede4ffae60500331 Mon Sep 17 00:00:00 2001 From: ahmetfarukulu Date: Wed, 1 Feb 2023 17:02:29 +0300 Subject: [PATCH 7/8] Update Background-Jobs.md --- docs/en/Background-Jobs.md | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/docs/en/Background-Jobs.md b/docs/en/Background-Jobs.md index 84e746f73d..a4eee9f978 100644 --- a/docs/en/Background-Jobs.md +++ b/docs/en/Background-Jobs.md @@ -75,6 +75,49 @@ This job simply uses `IEmailSender` to send emails (see [email sending document] A background job should not hide exceptions. If it throws an exception, the background job is automatically re-tried after a calculated waiting time. Hide exceptions only if you don't want to re-run the background job for the current argument. +#### Cancelling Background Jobs + +If you use cancellation supported background job system. You can check cancellation token via `ICancellationTokenProvider`. + +**Example** + +```csharp +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; + +namespace MyProject +{ + public class LongRunningJob : AsyncBackgroundJob, ITransientDependency + { + private readonly ICancellationTokenProvider _cancellationTokenProvider; + + public LongRunningJob(ICancellationTokenProvider cancellationTokenProvider) + { + _cancellationTokenProvider = cancellationTokenProvider; + } + + public override async Task ExecuteAsync(LongRunningJobArgs args) + { + try + { + foreach (var id in args.Ids) + { + _cancellationTokenProvider.Token.ThrowIfCancellationRequested(); + await ProcessAsync(id);//code omitted for brevity + } + } + catch (OperationCanceledException) + { + Logger.LogWarning("Job cancelled!"); + } + } + } +} +``` + #### Job Name Each background job has a name. Job names are used in several places. For example, RabbitMQ provider uses job names to determine the RabbitMQ Queue names. From 0b0060f8d7f1c34c402490c8f7b040bbdafd4a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 28 Feb 2023 08:40:14 +0300 Subject: [PATCH 8/8] Enhance the Cancelling Background Jobs section of Background-Jobs document --- docs/en/Background-Jobs.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/docs/en/Background-Jobs.md b/docs/en/Background-Jobs.md index a4eee9f978..c6e19fb48a 100644 --- a/docs/en/Background-Jobs.md +++ b/docs/en/Background-Jobs.md @@ -77,9 +77,7 @@ A background job should not hide exceptions. If it throws an exception, the back #### Cancelling Background Jobs -If you use cancellation supported background job system. You can check cancellation token via `ICancellationTokenProvider`. - -**Example** +If your background task is cancellable, then you can use the standard [Cancellation Token](Cancellation-Token-Provider.md) system to obtain a `CancellationToken` to cancel your job when requested. See the following example that uses the `ICancellationTokenProvider` to obtain the cancellation token: ```csharp using System; @@ -101,23 +99,18 @@ namespace MyProject public override async Task ExecuteAsync(LongRunningJobArgs args) { - try + foreach (var id in args.Ids) { - foreach (var id in args.Ids) - { - _cancellationTokenProvider.Token.ThrowIfCancellationRequested(); - await ProcessAsync(id);//code omitted for brevity - } - } - catch (OperationCanceledException) - { - Logger.LogWarning("Job cancelled!"); + _cancellationTokenProvider.Token.ThrowIfCancellationRequested(); + await ProcessAsync(id); // code omitted for brevity } } } } ``` +> A cancellation operation might be needed if the application is shutting down and we don't want to block the application in the background job. This example throws an exception if the cancellation is requested. So, the job will be retried the next time the application starts. If you don't want that, just return from the `ExecuteAsync` method without throwing any exception (you can simply check the `_cancellationTokenProvider.Token.IsCancellationRequested` property). + #### Job Name Each background job has a name. Job names are used in several places. For example, RabbitMQ provider uses job names to determine the RabbitMQ Queue names.