Browse Source

Merge pull request #3382 from liangshiw/liangshiwei/backgrondjob-isenabled

Refactoring background jobs&worker integration
pull/4021/head
Halil İbrahim Kalkan 7 years ago
committed by GitHub
parent
commit
4ea987908f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobOptions.cs
  2. 24
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs
  3. 2
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs
  4. 17
      framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs
  5. 46
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobQuartzOptions.cs
  6. 18
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs
  7. 22
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManageExtensions.cs
  8. 37
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs
  9. 29
      framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs
  10. 10
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkerQuartzOptions.cs
  11. 31
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs
  12. 8
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorker.cs
  13. 7
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerBase.cs
  14. 36
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs
  15. 31
      framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs
  16. 48
      framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs
  17. 23
      framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs

3
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/AbpBackgroundJobOptions.cs

@ -8,8 +8,7 @@ namespace Volo.Abp.BackgroundJobs
{ {
private readonly Dictionary<Type, BackgroundJobConfiguration> _jobConfigurationsByArgsType; private readonly Dictionary<Type, BackgroundJobConfiguration> _jobConfigurationsByArgsType;
private readonly Dictionary<string, BackgroundJobConfiguration> _jobConfigurationsByName; private readonly Dictionary<string, BackgroundJobConfiguration> _jobConfigurationsByName;
//TODO: Implement for all providers! (Hangfire does not implement yet)
/// <summary> /// <summary>
/// Default: true. /// Default: true.
/// </summary> /// </summary>

24
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs

@ -1,4 +1,8 @@
using Volo.Abp.Hangfire; using System;
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Hangfire;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.BackgroundJobs.Hangfire namespace Volo.Abp.BackgroundJobs.Hangfire
@ -6,9 +10,23 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
[DependsOn( [DependsOn(
typeof(AbpBackgroundJobsAbstractionsModule), typeof(AbpBackgroundJobsAbstractionsModule),
typeof(AbpHangfireModule) typeof(AbpHangfireModule)
)] )]
public class AbpBackgroundJobsHangfireModule : AbpModule public class AbpBackgroundJobsHangfireModule : AbpModule
{ {
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundJobOptions>>().Value;
if (!options.IsJobExecutionEnabled)
{
var hangfireOptions = context.ServiceProvider.GetRequiredService<IOptions<AbpHangfireOptions>>().Value;
hangfireOptions.BackgroundJobServerFactory = CreateOnlyEnqueueJobServer;
}
}
private BackgroundJobServer CreateOnlyEnqueueJobServer(IServiceProvider serviceProvider)
{
serviceProvider.GetRequiredService<JobStorage>();
return null;
}
} }
} }

2
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireBackgroundJobManager.cs

@ -8,7 +8,7 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
[Dependency(ReplaceServices = true)] [Dependency(ReplaceServices = true)]
public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDependency public class HangfireBackgroundJobManager : IBackgroundJobManager, ITransientDependency
{ {
public Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, public virtual Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
TimeSpan? delay = null) TimeSpan? delay = null)
{ {
if (!delay.HasValue) if (!delay.HasValue)

17
framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/HangfireJobExecutionAdapter.cs

@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Threading; using Volo.Abp.Threading;
@ -6,22 +8,31 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
{ {
public class HangfireJobExecutionAdapter<TArgs> public class HangfireJobExecutionAdapter<TArgs>
{ {
public ILogger<HangfireJobExecutionAdapter<TArgs>> Logger { get; set; }
protected AbpBackgroundJobOptions Options { get; } protected AbpBackgroundJobOptions Options { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; } protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; } protected IBackgroundJobExecuter JobExecuter { get; }
public HangfireJobExecutionAdapter( public HangfireJobExecutionAdapter(
IOptions<AbpBackgroundJobOptions> options, IOptions<AbpBackgroundJobOptions> options,
IBackgroundJobExecuter jobExecuter, IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory) IServiceScopeFactory serviceScopeFactory)
{ {
JobExecuter = jobExecuter; JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory; ServiceScopeFactory = serviceScopeFactory;
Options = options.Value; Options = options.Value;
Logger = NullLogger<HangfireJobExecutionAdapter<TArgs>>.Instance;
} }
public void Execute(TArgs args) public void Execute(TArgs args)
{ {
if (!Options.IsJobExecutionEnabled)
{
Logger.LogWarning("Background jobs system is disabled");
return;
}
using (var scope = ServiceScopeFactory.CreateScope()) using (var scope = ServiceScopeFactory.CreateScope())
{ {
var jobType = Options.GetJob(typeof(TArgs)).JobType; var jobType = Options.GetJob(typeof(TArgs)).JobType;
@ -30,4 +41,4 @@ namespace Volo.Abp.BackgroundJobs.Hangfire
} }
} }
} }
} }

46
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobQuartzOptions.cs

@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Quartz;
namespace Volo.Abp.BackgroundJobs.Quartz
{
public class AbpBackgroundJobQuartzOptions
{
public int RetryCount { get; set; }
public int RetryIntervalMillisecond { get; set; }
[NotNull]
public Func<int, IJobExecutionContext, JobExecutionException,Task> RetryStrategy
{
get => _retryStrategy;
set => _retryStrategy = Check.NotNull(value, nameof(value));
}
private Func<int, IJobExecutionContext, JobExecutionException,Task> _retryStrategy;
public AbpBackgroundJobQuartzOptions()
{
RetryCount = 3;
RetryIntervalMillisecond = 3000;
_retryStrategy = DefaultRetryStrategy;
}
private async Task DefaultRetryStrategy(int retryIndex, IJobExecutionContext executionContext, JobExecutionException exception)
{
exception.RefireImmediately = true;
var retryCount = executionContext.JobDetail.JobDataMap.GetIntValue(QuartzBackgroundJobManager.JobDataPrefix+ nameof(RetryCount));
if (retryIndex > retryCount)
{
exception.RefireImmediately = false;
exception.UnscheduleAllTriggers = true;
return;
}
var retryInterval = executionContext.JobDetail.JobDataMap.GetIntValue(QuartzBackgroundJobManager.JobDataPrefix+ nameof(RetryIntervalMillisecond));
await Task.Delay(retryInterval);
}
}
}

18
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs

@ -1,4 +1,6 @@
using Microsoft.Extensions.DependencyInjection; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Quartz; using Volo.Abp.Quartz;
@ -8,11 +10,21 @@ namespace Volo.Abp.BackgroundJobs.Quartz
typeof(AbpBackgroundJobsAbstractionsModule), typeof(AbpBackgroundJobsAbstractionsModule),
typeof(AbpQuartzModule) typeof(AbpQuartzModule)
)] )]
public class AbpBackgroundJobsQuartzModule :AbpModule public class AbpBackgroundJobsQuartzModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.AddTransient(typeof(QuartzJobExecutionAdapter<>)); context.Services.AddTransient(typeof(QuartzJobExecutionAdapter<>));
} }
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetService<IOptions<AbpBackgroundJobOptions>>().Value;
if (!options.IsJobExecutionEnabled)
{
var quartzOptions = context.ServiceProvider.GetService<IOptions<AbpQuartzOptions>>().Value;
quartzOptions.StartSchedulerFactory = scheduler => Task.CompletedTask;
}
}
} }
} }

22
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManageExtensions.cs

@ -0,0 +1,22 @@
using System;
using System.Threading.Tasks;
using Quartz;
namespace Volo.Abp.BackgroundJobs.Quartz
{
public static class QuartzBackgroundJobManageExtensions
{
public static async Task<string> EnqueueAsync<TArgs>(this IBackgroundJobManager backgroundJobManager,
TArgs args, int retryCount, int retryIntervalMillisecond,
BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null)
{
if (backgroundJobManager is QuartzBackgroundJobManager quartzBackgroundJobManager)
{
return await quartzBackgroundJobManager.ReEnqueueAsync(args, retryCount, retryIntervalMillisecond,
priority, delay);
}
return null;
}
}
}

37
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzBackgroundJobManager.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Quartz; using Quartz;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -7,20 +8,40 @@ namespace Volo.Abp.BackgroundJobs.Quartz
{ {
[Dependency(ReplaceServices = true)] [Dependency(ReplaceServices = true)]
public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDependency public class QuartzBackgroundJobManager : IBackgroundJobManager, ITransientDependency
{ {
private readonly IScheduler _scheduler; public const string JobDataPrefix = "Abp";
public const string RetryIndex = "RetryIndex";
public QuartzBackgroundJobManager(IScheduler scheduler)
protected IScheduler Scheduler { get; }
protected AbpBackgroundJobQuartzOptions Options { get; }
public QuartzBackgroundJobManager(IScheduler scheduler,IOptions<AbpBackgroundJobQuartzOptions> options)
{ {
_scheduler = scheduler; Scheduler = scheduler;
Options = options.Value;
} }
public async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, public virtual async Task<string> EnqueueAsync<TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal,
TimeSpan? delay = null) TimeSpan? delay = null)
{ {
var jobDetail = JobBuilder.Create<QuartzJobExecutionAdapter<TArgs>>().SetJobData(new JobDataMap { { nameof(TArgs), args } }).Build(); return await ReEnqueueAsync(args, Options.RetryCount, Options.RetryIntervalMillisecond, priority, delay);
}
public virtual async Task<string> ReEnqueueAsync<TArgs>(TArgs args, int retryCount, int retryIntervalMillisecond,
BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan? delay = null)
{
var jobDataMap = new JobDataMap
{
{nameof(TArgs), args},
{JobDataPrefix+ nameof(Options.RetryCount), retryCount},
{JobDataPrefix+ nameof(Options.RetryIntervalMillisecond), retryIntervalMillisecond},
{JobDataPrefix+ RetryIndex, 0}
};
var jobDetail = JobBuilder.Create<QuartzJobExecutionAdapter<TArgs>>().RequestRecovery().SetJobData(jobDataMap).Build();
var trigger = !delay.HasValue ? TriggerBuilder.Create().StartNow().Build() : TriggerBuilder.Create().StartAt(new DateTimeOffset(DateTime.Now.Add(delay.Value))).Build(); var trigger = !delay.HasValue ? TriggerBuilder.Create().StartNow().Build() : TriggerBuilder.Create().StartAt(new DateTimeOffset(DateTime.Now.Add(delay.Value))).Build();
await _scheduler.ScheduleJob(jobDetail, trigger); await Scheduler.ScheduleJob(jobDetail, trigger);
return jobDetail.Key.ToString(); return jobDetail.Key.ToString();
} }
} }

29
framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/QuartzJobExecutionAdapter.cs

@ -1,6 +1,8 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Quartz; using Quartz;
@ -8,29 +10,50 @@ namespace Volo.Abp.BackgroundJobs.Quartz
{ {
public class QuartzJobExecutionAdapter<TArgs> : IJob public class QuartzJobExecutionAdapter<TArgs> : IJob
{ {
public ILogger<QuartzJobExecutionAdapter<TArgs>> Logger { get; set; }
protected AbpBackgroundJobOptions Options { get; } protected AbpBackgroundJobOptions Options { get; }
protected AbpBackgroundJobQuartzOptions BackgroundJobQuartzOptions { get; }
protected IServiceScopeFactory ServiceScopeFactory { get; } protected IServiceScopeFactory ServiceScopeFactory { get; }
protected IBackgroundJobExecuter JobExecuter { get; } protected IBackgroundJobExecuter JobExecuter { get; }
public QuartzJobExecutionAdapter( public QuartzJobExecutionAdapter(
IOptions<AbpBackgroundJobOptions> options, IOptions<AbpBackgroundJobOptions> options,
IOptions<AbpBackgroundJobQuartzOptions> backgroundJobQuartzOptions,
IBackgroundJobExecuter jobExecuter, IBackgroundJobExecuter jobExecuter,
IServiceScopeFactory serviceScopeFactory) IServiceScopeFactory serviceScopeFactory)
{ {
JobExecuter = jobExecuter; JobExecuter = jobExecuter;
ServiceScopeFactory = serviceScopeFactory; ServiceScopeFactory = serviceScopeFactory;
Options = options.Value; Options = options.Value;
BackgroundJobQuartzOptions = backgroundJobQuartzOptions.Value;
Logger = NullLogger<QuartzJobExecutionAdapter<TArgs>>.Instance;
} }
public async Task Execute(IJobExecutionContext context) public async Task Execute(IJobExecutionContext context)
{ {
using (var scope = ServiceScopeFactory.CreateScope()) using (var scope = ServiceScopeFactory.CreateScope())
{ {
var args = (TArgs)context.JobDetail.JobDataMap.Get(nameof(TArgs)); var args = (TArgs) context.JobDetail.JobDataMap.Get(nameof(TArgs));
var jobType = Options.GetJob(typeof(TArgs)).JobType; var jobType = Options.GetJob(typeof(TArgs)).JobType;
var jobContext = new JobExecutionContext(scope.ServiceProvider, jobType, args); var jobContext = new JobExecutionContext(scope.ServiceProvider, jobType, args);
await JobExecuter.ExecuteAsync(jobContext); try
{
await JobExecuter.ExecuteAsync(jobContext);
}
catch (Exception exception)
{
var jobExecutionException = new JobExecutionException(exception);
var retryIndex = context.JobDetail.JobDataMap.GetIntValue(QuartzBackgroundJobManager.JobDataPrefix+ QuartzBackgroundJobManager.RetryIndex);
retryIndex++;
context.JobDetail.JobDataMap.Put(QuartzBackgroundJobManager.JobDataPrefix+ QuartzBackgroundJobManager.RetryIndex, retryIndex);
await BackgroundJobQuartzOptions.RetryStrategy.Invoke(retryIndex, context, jobExecutionException);
throw jobExecutionException;
}
} }
} }
} }
} }

10
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkerQuartzOptions.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.BackgroundWorkers.Quartz
{
public class AbpBackgroundWorkerQuartzOptions
{
/// <summary>
/// Default : true.
/// </summary>
public bool IsAutoRegisterEnabled { get; set; } = true;
}
}

31
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs

@ -1,5 +1,7 @@
using Microsoft.Extensions.DependencyInjection; using System.Linq;
using Microsoft.Extensions.DependencyInjection.Extensions; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Quartz; using Volo.Abp.Quartz;
@ -15,15 +17,30 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
{ {
context.Services.AddConventionalRegistrar(new AbpQuartzConventionalRegistrar()); context.Services.AddConventionalRegistrar(new AbpQuartzConventionalRegistrar());
} }
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetService<IOptions<AbpBackgroundWorkerOptions>>().Value;
if (!options.IsEnabled)
{
var quartzOptions = context.ServiceProvider.GetService<IOptions<AbpQuartzOptions>>().Value;
quartzOptions.StartSchedulerFactory = scheduler => Task.CompletedTask;
}
}
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
var backgroundWorkerManager = context.ServiceProvider.GetService<IBackgroundWorkerManager>(); var options = context.ServiceProvider.GetService<IOptions<AbpBackgroundWorkerOptions>>().Value;
var works = context.ServiceProvider.GetServices<IQuartzBackgroundWorker>(); var quartzBackgroundWorkerOptions = context.ServiceProvider.GetService<IOptions<AbpBackgroundWorkerQuartzOptions>>().Value;
if (options.IsEnabled && quartzBackgroundWorkerOptions.IsAutoRegisterEnabled)
foreach (var work in works)
{ {
backgroundWorkerManager.Add(work); var backgroundWorkerManager = context.ServiceProvider.GetService<IBackgroundWorkerManager>();
var works = context.ServiceProvider.GetServices<IQuartzBackgroundWorker>().Where(x=>x.AutoRegister);
foreach (var work in works)
{
backgroundWorkerManager.Add(work);
}
} }
} }
} }

8
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/IQuartzBackgroundWorker.cs

@ -1,4 +1,6 @@
using Quartz; using System;
using System.Threading.Tasks;
using Quartz;
namespace Volo.Abp.BackgroundWorkers.Quartz namespace Volo.Abp.BackgroundWorkers.Quartz
{ {
@ -7,5 +9,9 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
ITrigger Trigger { get; set; } ITrigger Trigger { get; set; }
IJobDetail JobDetail { get; set; } IJobDetail JobDetail { get; set; }
bool AutoRegister { get; set; }
Func<IScheduler,Task> ScheduleJob { get; set; }
} }
} }

7
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerBase.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks; using System;
using System.Threading.Tasks;
using Quartz; using Quartz;
namespace Volo.Abp.BackgroundWorkers.Quartz namespace Volo.Abp.BackgroundWorkers.Quartz
@ -8,6 +9,10 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
public ITrigger Trigger { get; set; } public ITrigger Trigger { get; set; }
public IJobDetail JobDetail { get; set; } public IJobDetail JobDetail { get; set; }
public bool AutoRegister { get; set; } = true;
public Func<IScheduler, Task> ScheduleJob { get; set; } = null;
public abstract Task Execute(IJobExecutionContext context); public abstract Task Execute(IJobExecutionContext context);
} }

36
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs

@ -16,12 +16,12 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
_scheduler = scheduler; _scheduler = scheduler;
} }
public async Task StartAsync(CancellationToken cancellationToken = default) public virtual async Task StartAsync(CancellationToken cancellationToken = default)
{ {
await _scheduler.ResumeAll(cancellationToken); await _scheduler.ResumeAll(cancellationToken);
} }
public async Task StopAsync(CancellationToken cancellationToken = default) public virtual async Task StopAsync(CancellationToken cancellationToken = default)
{ {
if (!_scheduler.IsShutdown) if (!_scheduler.IsShutdown)
{ {
@ -29,15 +29,41 @@ namespace Volo.Abp.BackgroundWorkers.Quartz
} }
} }
public void Add(IBackgroundWorker worker) public virtual void Add(IBackgroundWorker worker)
{
AsyncHelper.RunSync(() => ReScheduleJobAsync(worker));
}
protected virtual async Task ReScheduleJobAsync(IBackgroundWorker worker)
{ {
if (worker is IQuartzBackgroundWorker quartzWork) if (worker is IQuartzBackgroundWorker quartzWork)
{ {
Check.NotNull(quartzWork.Trigger, nameof(quartzWork.Trigger)); Check.NotNull(quartzWork.Trigger, nameof(quartzWork.Trigger));
Check.NotNull(quartzWork.JobDetail, nameof(quartzWork.JobDetail)); Check.NotNull(quartzWork.JobDetail, nameof(quartzWork.JobDetail));
AsyncHelper.RunSync(() => _scheduler.ScheduleJob(quartzWork.JobDetail, quartzWork.Trigger)); if (quartzWork.ScheduleJob != null)
{
await quartzWork.ScheduleJob.Invoke(_scheduler);
}
else
{
await DefaultScheduleJobAsync(quartzWork);
}
}
}
protected virtual async Task DefaultScheduleJobAsync(IQuartzBackgroundWorker quartzWork)
{
if (await _scheduler.CheckExists(quartzWork.JobDetail.Key))
{
await _scheduler.AddJob(quartzWork.JobDetail, true, true);
await _scheduler.ResumeJob(quartzWork.JobDetail.Key);
await _scheduler.RescheduleJob(quartzWork.Trigger.Key, quartzWork.Trigger);
}
else
{
await _scheduler.ScheduleJob(quartzWork.JobDetail, quartzWork.Trigger);
} }
} }
} }
} }

31
framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs

@ -14,32 +14,33 @@ namespace Volo.Abp.Quartz
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
var options = context.Services.ExecutePreConfiguredActions<AbpQuartzPreOptions>(); var options = context.Services.ExecutePreConfiguredActions<AbpQuartzOptions>();
context.Services.AddSingleton(AsyncHelper.RunSync(() => new StdSchedulerFactory(options.Properties).GetScheduler())); context.Services.AddSingleton(AsyncHelper.RunSync(() => new StdSchedulerFactory(options.Properties).GetScheduler()));
context.Services.AddSingleton(typeof(IJobFactory), typeof(AbpQuartzJobFactory)); context.Services.AddSingleton(typeof(IJobFactory), typeof(AbpQuartzJobFactory));
Configure<AbpQuartzOptions>(quartzOptions =>
{
quartzOptions.Properties = options.Properties;
quartzOptions.StartDelay = options.StartDelay;
});
} }
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpQuartzPreOptions>>().Value; var options = context.ServiceProvider.GetRequiredService<IOptions<AbpQuartzOptions>>().Value;
_scheduler = context.ServiceProvider.GetService<IScheduler>(); _scheduler = context.ServiceProvider.GetService<IScheduler>();
_scheduler.JobFactory = context.ServiceProvider.GetService<IJobFactory>(); _scheduler.JobFactory = context.ServiceProvider.GetService<IJobFactory>();
if (options.StartDelay.Ticks > 0) AsyncHelper.RunSync(() => options.StartSchedulerFactory.Invoke(_scheduler));
{
AsyncHelper.RunSync(() => _scheduler.StartDelayed(options.StartDelay));
}
else
{
AsyncHelper.RunSync(() => _scheduler.Start());
}
} }
public override void OnApplicationShutdown(ApplicationShutdownContext context) public override void OnApplicationShutdown(ApplicationShutdownContext context)
{ {
//TODO: ABP may provide two methods for application shutdown: OnPreApplicationShutdown & OnApplicationShutdown if (_scheduler.IsStarted)
AsyncHelper.RunSync(() => _scheduler.Shutdown()); {
AsyncHelper.RunSync(() => _scheduler.Shutdown());
}
} }
} }
} }

48
framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs

@ -0,0 +1,48 @@
using System;
using System.Collections.Specialized;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Quartz;
namespace Volo.Abp.Quartz
{
public class AbpQuartzOptions
{
/// <summary>
/// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory.
/// </summary>
public NameValueCollection Properties { get; set; }
/// <summary>
/// How long Quartz should wait before starting. Default: 0.
/// </summary>
public TimeSpan StartDelay { get; set; }
[NotNull]
public Func<IScheduler, Task> StartSchedulerFactory
{
get => _startSchedulerFactory;
set => _startSchedulerFactory = Check.NotNull(value, nameof(value));
}
private Func<IScheduler, Task> _startSchedulerFactory;
public AbpQuartzOptions()
{
Properties = new NameValueCollection();
StartDelay = new TimeSpan(0);
_startSchedulerFactory = StartSchedulerAsync;
}
private async Task StartSchedulerAsync(IScheduler scheduler)
{
if (StartDelay.Ticks > 0)
{
await scheduler.StartDelayed(StartDelay);
}
else
{
await scheduler.Start();
}
}
}
}

23
framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs

@ -1,23 +0,0 @@
using System;
using System.Collections.Specialized;
namespace Volo.Abp.Quartz
{
public class AbpQuartzPreOptions
{
/// <summary>
/// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory.
/// </summary>
public NameValueCollection Properties { get; set; }
/// <summary>
/// How long Quartz should wait before starting. Default: 0.
/// </summary>
public TimeSpan StartDelay { get; set; }
public AbpQuartzPreOptions()
{
Properties = new NameValueCollection();
StartDelay = new TimeSpan(0);
}
}
}
Loading…
Cancel
Save