diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs index e5d0dbe9a5..0613633893 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs @@ -30,7 +30,7 @@ namespace Volo.Abp.BackgroundJobs .GetRequiredService() .Add( context.ServiceProvider - .GetRequiredService() + .GetRequiredService() ); } } diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs index ccbe5cd28b..793b993fbc 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs @@ -50,7 +50,7 @@ namespace Volo.Abp.BackgroundJobs var job = scope.ServiceProvider.GetService(jobType); if (job == null) { - throw new AbpException("JobName is not registered: " + jobType); + throw new AbpException("The job type is not registered to DI: " + jobType); } //TODO: Type check for the job object diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobManager.cs index 5751159a4a..e03cc63793 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobManager.cs @@ -1,37 +1,21 @@ using System; using System.Threading.Tasks; -using Volo.Abp.BackgroundWorkers; using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; -using Volo.Abp.Threading; using Volo.Abp.Timing; namespace Volo.Abp.BackgroundJobs { - //TODO: Split enqueueing & background worker! - /// /// Default implementation of . /// - public class BackgroundJobManager : PeriodicBackgroundWorkerBase, IBackgroundJobManager, ISingletonDependency + public class BackgroundJobManager : IBackgroundJobManager, ISingletonDependency { - /// - /// Interval between polling jobs from . - /// Default value: 5000 (5 seconds). - /// - public static int JobPollPeriod { get; set; } //TODO: Move to options - protected IClock Clock { get; } protected IBackgroundJobSerializer Serializer { get; } protected IGuidGenerator GuidGenerator { get; } - protected IBackgroundJobExecuter JobExecuter { get; } protected IBackgroundJobStore Store { get; } - - static BackgroundJobManager() - { - JobPollPeriod = 5000; - } - + /// /// Initializes a new instance of the class. /// @@ -39,18 +23,12 @@ namespace Volo.Abp.BackgroundJobs IClock clock, IBackgroundJobSerializer serializer, IBackgroundJobStore store, - IGuidGenerator guidGenerator, - AbpTimer timer, - IBackgroundJobExecuter jobExecuter) - : base(timer) + IGuidGenerator guidGenerator) { Clock = clock; Serializer = serializer; GuidGenerator = guidGenerator; - JobExecuter = jobExecuter; Store = store; - - Timer.Period = JobPollPeriod; } public Task EnqueueAsync(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null) @@ -80,15 +58,5 @@ namespace Volo.Abp.BackgroundJobs return jobInfo.Id; } - - protected override void DoWork() - { - var waitingJobs = AsyncHelper.RunSync(() => Store.GetWaitingJobsAsync(1000)); - - foreach (var job in waitingJobs) - { - JobExecuter.Execute(job); - } - } } } diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobOptions.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobOptions.cs index 42d6999993..ad40c0428b 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobOptions.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobOptions.cs @@ -5,6 +5,7 @@ namespace Volo.Abp.BackgroundJobs { public class BackgroundJobOptions { + //TODO: Consider to automatically register jobs public Dictionary JobTypes { get; } public bool IsJobExecutionEnabled { get; set; } @@ -15,9 +16,10 @@ namespace Volo.Abp.BackgroundJobs JobTypes = new Dictionary(); } - public Type GetJobType(string jobName) + internal Type GetJobType(string jobName) { var jobType = JobTypes.GetOrDefault(jobName); + if (jobType == null) { throw new AbpException("Undefined background job type for the job name: " + jobName); diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs new file mode 100644 index 0000000000..126d48ee42 --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs @@ -0,0 +1,52 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.BackgroundWorkers; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Guids; +using Volo.Abp.Threading; +using Volo.Abp.Timing; + +namespace Volo.Abp.BackgroundJobs +{ + public class BackgroundJobWorker : PeriodicBackgroundWorkerBase, IBackgroundJobWorker, ISingletonDependency + { + /// + /// Interval between polling jobs from . + /// Default value: 5000 (5 seconds). + /// + public static int JobPollPeriod { get; set; } //TODO: Move to options + + protected IBackgroundJobExecuter JobExecuter { get; } + protected IBackgroundJobStore Store { get; } + + static BackgroundJobWorker() + { + JobPollPeriod = 5000; + } + + /// + /// Initializes a new instance of the class. + /// + public BackgroundJobWorker( + IBackgroundJobStore store, + AbpTimer timer, + IBackgroundJobExecuter jobExecuter) + : base(timer) + { + JobExecuter = jobExecuter; + Store = store; + + Timer.Period = JobPollPeriod; + } + + protected override void DoWork() + { + var waitingJobs = AsyncHelper.RunSync(() => Store.GetWaitingJobsAsync(1000)); + + foreach (var job in waitingJobs) + { + JobExecuter.Execute(job); + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobManager.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobManager.cs index 238e46d520..bea7c648a0 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobManager.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobManager.cs @@ -1,14 +1,12 @@ using System; using System.Threading.Tasks; -using Volo.Abp.BackgroundWorkers; namespace Volo.Abp.BackgroundJobs { - //TODO: Create a non-generic EnqueueAsync extension method to IBackgroundJobManager which takes types as input parameters rather than generic parameters. /// /// Defines interface of a job manager. /// - public interface IBackgroundJobManager : IBackgroundWorker + public interface IBackgroundJobManager { /// /// Enqueues a job to be executed. diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobWorker.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobWorker.cs new file mode 100644 index 0000000000..09be0e5ac1 --- /dev/null +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobWorker.cs @@ -0,0 +1,9 @@ +using Volo.Abp.BackgroundWorkers; + +namespace Volo.Abp.BackgroundJobs +{ + public interface IBackgroundJobWorker : IBackgroundWorker + { + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs index 2b9d8700dc..405b96060e 100644 --- a/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs +++ b/framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs @@ -25,7 +25,7 @@ namespace Volo.Abp.BackgroundJobs public Task FindAsync(Guid jobId) { - return Task.FromResult(_jobs[jobId]); + return Task.FromResult(_jobs.GetOrDefault(jobId)); } public Task InsertAsync(BackgroundJobInfo jobInfo) diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/AbpBackgroundJobsTestModule.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/AbpBackgroundJobsTestModule.cs index 084265a51f..a359ed3b7d 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/AbpBackgroundJobsTestModule.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/AbpBackgroundJobsTestModule.cs @@ -10,6 +10,12 @@ namespace Volo.Abp.BackgroundJobs { public override void ConfigureServices(ServiceConfigurationContext context) { + //TODO: Can we automatically register these! + context.Services.Configure(options => + { + options.JobTypes[MyJobArgs.Name] = typeof(MyJob); + }); + context.Services.AddAssemblyOf(); } } 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 new file mode 100644 index 0000000000..f2c38d07c3 --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs @@ -0,0 +1,45 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.BackgroundJobs +{ + public class BackgroundJobExecuter_Tests : BackgroundJobsTestBase + { + private readonly IBackgroundJobExecuter _backgroundJobExecuter; + private readonly IBackgroundJobManager _backgroundJobManager; + private readonly IBackgroundJobStore _backgroundJobStore; + + public BackgroundJobExecuter_Tests() + { + _backgroundJobExecuter = GetRequiredService(); + _backgroundJobManager = GetRequiredService(); + _backgroundJobStore = GetRequiredService(); + } + + [Fact] + public async Task Should_Execute_Tasks() + { + //Arrange + + var jobObject = GetRequiredService(); + jobObject.ExecutedValues.ShouldBeEmpty(); + + var jobId = await _backgroundJobManager.EnqueueAsync(new MyJobArgs("42")); + + var job = await _backgroundJobStore.FindAsync(jobId); + job.ShouldNotBeNull(); + + //Act + + _backgroundJobExecuter.Execute(job); + + //Assert + + jobObject.ExecutedValues.ShouldContain("42"); + + job = await _backgroundJobStore.FindAsync(jobId); + job.ShouldBeNull(); //Because it's deleted after the execution + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs index ab9dc5950a..526af109b6 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs @@ -22,21 +22,5 @@ namespace Volo.Abp.BackgroundJobs jobId.ShouldNotBe(default); (await _backgroundJobStore.FindAsync(jobId)).ShouldNotBeNull(); } - - [BackgroundJobName("TestJobs.MyJob")] - private class MyJobArgs - { - public string Value { get; set; } - - public MyJobArgs() - { - - } - - public MyJobArgs(string value) - { - Value = value; - } - } } } 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 new file mode 100644 index 0000000000..a9719c2cf4 --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.BackgroundJobs +{ + public class MyJob : BackgroundJob, ISingletonDependency + { + public List ExecutedValues { get; } = new List(); + + public override void Execute(MyJobArgs args) + { + ExecutedValues.Add(args.Value); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJobArgs.cs b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJobArgs.cs new file mode 100644 index 0000000000..e1254ee565 --- /dev/null +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJobArgs.cs @@ -0,0 +1,20 @@ +namespace Volo.Abp.BackgroundJobs +{ + [BackgroundJobName(Name)] + public class MyJobArgs + { + public const string Name = "TestJobs.MyJob"; + + public string Value { get; set; } + + public MyJobArgs() + { + + } + + public MyJobArgs(string value) + { + Value = value; + } + } +} \ No newline at end of file