Browse Source

Refactored and added tests for the background job system.

pull/395/head
Halil ibrahim Kalkan 8 years ago
parent
commit
e2e39caea4
  1. 2
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs
  2. 2
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobExecuter.cs
  3. 38
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobManager.cs
  4. 4
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobOptions.cs
  5. 52
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/BackgroundJobWorker.cs
  6. 4
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobManager.cs
  7. 9
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/IBackgroundJobWorker.cs
  8. 2
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs
  9. 6
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/AbpBackgroundJobsTestModule.cs
  10. 45
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobExecuter_Tests.cs
  11. 16
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/BackgroundJobManager_Tests.cs
  12. 15
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJob.cs
  13. 20
      framework/test/Volo.Abp.BackgroundJobs.Tests/Volo/Abp/BackgroundJobs/MyJobArgs.cs

2
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs

@ -30,7 +30,7 @@ namespace Volo.Abp.BackgroundJobs
.GetRequiredService<IBackgroundWorkerManager>()
.Add(
context.ServiceProvider
.GetRequiredService<IBackgroundJobManager>()
.GetRequiredService<IBackgroundJobWorker>()
);
}
}

2
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

38
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!
/// <summary>
/// Default implementation of <see cref="IBackgroundJobManager"/>.
/// </summary>
public class BackgroundJobManager : PeriodicBackgroundWorkerBase, IBackgroundJobManager, ISingletonDependency
public class BackgroundJobManager : IBackgroundJobManager, ISingletonDependency
{
/// <summary>
/// Interval between polling jobs from <see cref="IBackgroundJobStore"/>.
/// Default value: 5000 (5 seconds).
/// </summary>
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;
}
/// <summary>
/// Initializes a new instance of the <see cref="BackgroundJobManager"/> class.
/// </summary>
@ -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<Guid> EnqueueAsync<TArgs>(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);
}
}
}
}

4
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<string, Type> JobTypes { get; }
public bool IsJobExecutionEnabled { get; set; }
@ -15,9 +16,10 @@ namespace Volo.Abp.BackgroundJobs
JobTypes = new Dictionary<string, Type>();
}
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);

52
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
{
/// <summary>
/// Interval between polling jobs from <see cref="IBackgroundJobStore"/>.
/// Default value: 5000 (5 seconds).
/// </summary>
public static int JobPollPeriod { get; set; } //TODO: Move to options
protected IBackgroundJobExecuter JobExecuter { get; }
protected IBackgroundJobStore Store { get; }
static BackgroundJobWorker()
{
JobPollPeriod = 5000;
}
/// <summary>
/// Initializes a new instance of the <see cref="BackgroundJobManager"/> class.
/// </summary>
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);
}
}
}
}

4
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.
/// <summary>
/// Defines interface of a job manager.
/// </summary>
public interface IBackgroundJobManager : IBackgroundWorker
public interface IBackgroundJobManager
{
/// <summary>
/// Enqueues a job to be executed.

9
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
{
}
}

2
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/InMemoryBackgroundJobStore.cs

@ -25,7 +25,7 @@ namespace Volo.Abp.BackgroundJobs
public Task<BackgroundJobInfo> FindAsync(Guid jobId)
{
return Task.FromResult(_jobs[jobId]);
return Task.FromResult(_jobs.GetOrDefault(jobId));
}
public Task InsertAsync(BackgroundJobInfo jobInfo)

6
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<BackgroundJobOptions>(options =>
{
options.JobTypes[MyJobArgs.Name] = typeof(MyJob);
});
context.Services.AddAssemblyOf<AbpBackgroundJobsTestModule>();
}
}

45
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<IBackgroundJobExecuter>();
_backgroundJobManager = GetRequiredService<IBackgroundJobManager>();
_backgroundJobStore = GetRequiredService<IBackgroundJobStore>();
}
[Fact]
public async Task Should_Execute_Tasks()
{
//Arrange
var jobObject = GetRequiredService<MyJob>();
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
}
}
}

16
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;
}
}
}
}

15
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<MyJobArgs>, ISingletonDependency
{
public List<string> ExecutedValues { get; } = new List<string>();
public override void Execute(MyJobArgs args)
{
ExecutedValues.Add(args.Value);
}
}
}

20
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;
}
}
}
Loading…
Cancel
Save