From 2f381fa48547938a237b106550b68e2692f42ebc Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 13 Apr 2020 12:37:22 +0800 Subject: [PATCH] Re-implemented background job & worker disable logic --- .../AbpBackgroundJobsHangfireModule.cs | 21 +++++++- .../Quartz/AbpBackgroundJobsQuartzModule.cs | 14 +++++- .../Quartz/QuartzJobExecutionAdapter.cs | 3 +- .../AbpBackgroundWorkersQuartzModule.cs | 29 ++++++++--- .../Quartz/QuartzBackgroundWorkerManager.cs | 20 ++++++-- .../Volo/Abp/Quartz/AbpQuartzModule.cs | 31 ++++++------ .../Volo/Abp/Quartz/AbpQuartzOptions.cs | 48 +++++++++++++++++++ .../Volo/Abp/Quartz/AbpQuartzPreOptions.cs | 23 --------- 8 files changed, 137 insertions(+), 52 deletions(-) create mode 100644 framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs delete mode 100644 framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs diff --git a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs b/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs index 27381f8e25..8e6802e751 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.HangFire/Volo/Abp/BackgroundJobs/Hangfire/AbpBackgroundJobsHangfireModule.cs +++ b/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; namespace Volo.Abp.BackgroundJobs.Hangfire @@ -9,5 +13,20 @@ namespace Volo.Abp.BackgroundJobs.Hangfire )] public class AbpBackgroundJobsHangfireModule : AbpModule { + public override void OnPreApplicationInitialization(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetRequiredService>().Value; + if (!options.IsJobExecutionEnabled) + { + var hangfireOptions = context.ServiceProvider.GetRequiredService>().Value; + hangfireOptions.BackgroundJobServerFactory = CreateOnlyEnqueueJobServer; + } + } + + private BackgroundJobServer CreateOnlyEnqueueJobServer(IServiceProvider serviceProvider) + { + serviceProvider.GetRequiredService(); + return null; + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs b/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs index 0e3d079acc..4c9366e93f 100644 --- a/framework/src/Volo.Abp.BackgroundJobs.Quartz/Volo/Abp/BackgroundJobs/Quartz/AbpBackgroundJobsQuartzModule.cs +++ b/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.Quartz; @@ -14,5 +16,15 @@ namespace Volo.Abp.BackgroundJobs.Quartz { context.Services.AddTransient(typeof(QuartzJobExecutionAdapter<>)); } + + public override void OnPreApplicationInitialization(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetService>().Value; + if (!options.IsJobExecutionEnabled) + { + var quartzOptions = context.ServiceProvider.GetService>().Value; + quartzOptions.StartSchedulerFactory = scheduler => Task.CompletedTask; + } + } } } \ No newline at end of file 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 2efe800c9c..5b77372959 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 @@ -1,5 +1,4 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs index 1f23b350aa..ff29887b30 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs @@ -1,5 +1,6 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.Modularity; using Volo.Abp.Quartz; @@ -15,15 +16,29 @@ namespace Volo.Abp.BackgroundWorkers.Quartz { context.Services.AddConventionalRegistrar(new AbpQuartzConventionalRegistrar()); } + + public override void OnPreApplicationInitialization(ApplicationInitializationContext context) + { + var options = context.ServiceProvider.GetService>().Value; + if (!options.IsEnabled) + { + var quartzOptions = context.ServiceProvider.GetService>().Value; + quartzOptions.StartSchedulerFactory = scheduler => Task.CompletedTask; + } + } public override void OnApplicationInitialization(ApplicationInitializationContext context) { - var backgroundWorkerManager = context.ServiceProvider.GetService(); - var works = context.ServiceProvider.GetServices(); - - foreach (var work in works) + var options = context.ServiceProvider.GetService>().Value; + if (options.IsEnabled) { - backgroundWorkerManager.Add(work); + var backgroundWorkerManager = context.ServiceProvider.GetService(); + var works = context.ServiceProvider.GetServices(); + + foreach (var work in works) + { + backgroundWorkerManager.Add(work); + } } } } diff --git a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs index 46568a5a11..db7fc692ff 100644 --- a/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs +++ b/framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs @@ -30,14 +30,28 @@ namespace Volo.Abp.BackgroundWorkers.Quartz } public void Add(IBackgroundWorker worker) + { + AsyncHelper.RunSync(() => ReScheduleJobAsync(worker)); + } + + private async Task ReScheduleJobAsync(IBackgroundWorker worker) { if (worker is IQuartzBackgroundWorker quartzWork) { Check.NotNull(quartzWork.Trigger, nameof(quartzWork.Trigger)); Check.NotNull(quartzWork.JobDetail, nameof(quartzWork.JobDetail)); - - AsyncHelper.RunSync(() => _scheduler.ScheduleJob(quartzWork.JobDetail, quartzWork.Trigger)); + + if (await _scheduler.CheckExists(quartzWork.JobDetail.Key)) + { + await _scheduler.AddJob(quartzWork.JobDetail, true); + await _scheduler.ResumeJob(quartzWork.JobDetail.Key); + await _scheduler.RescheduleJob(quartzWork.Trigger.Key, quartzWork.Trigger); + } + else + { + await _scheduler.ScheduleJob(quartzWork.JobDetail, quartzWork.Trigger); + } } } } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs index 9112f2baaf..3a2413a9b8 100644 --- a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs +++ b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzModule.cs @@ -14,32 +14,33 @@ namespace Volo.Abp.Quartz public override void ConfigureServices(ServiceConfigurationContext context) { - var options = context.Services.ExecutePreConfiguredActions(); + var options = context.Services.ExecutePreConfiguredActions(); context.Services.AddSingleton(AsyncHelper.RunSync(() => new StdSchedulerFactory(options.Properties).GetScheduler())); context.Services.AddSingleton(typeof(IJobFactory), typeof(AbpQuartzJobFactory)); + + Configure(quartzOptions => + { + quartzOptions.Properties = options.Properties; + quartzOptions.StartDelay = options.StartDelay; + }); } public override void OnApplicationInitialization(ApplicationInitializationContext context) { - var options = context.ServiceProvider.GetRequiredService>().Value; - + var options = context.ServiceProvider.GetRequiredService>().Value; + _scheduler = context.ServiceProvider.GetService(); _scheduler.JobFactory = context.ServiceProvider.GetService(); - - if (options.StartDelay.Ticks > 0) - { - AsyncHelper.RunSync(() => _scheduler.StartDelayed(options.StartDelay)); - } - else - { - AsyncHelper.RunSync(() => _scheduler.Start()); - } + + AsyncHelper.RunSync(() => options.StartSchedulerFactory.Invoke(_scheduler)); } public override void OnApplicationShutdown(ApplicationShutdownContext context) { - //TODO: ABP may provide two methods for application shutdown: OnPreApplicationShutdown & OnApplicationShutdown - AsyncHelper.RunSync(() => _scheduler.Shutdown()); + if (_scheduler.IsStarted) + { + AsyncHelper.RunSync(() => _scheduler.Shutdown()); + } } } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzOptions.cs new file mode 100644 index 0000000000..9998676042 --- /dev/null +++ b/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 + { + /// + /// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory. + /// + public NameValueCollection Properties { get; set; } + + /// + /// How long Quartz should wait before starting. Default: 0. + /// + public TimeSpan StartDelay { get; set; } + + [NotNull] + public Func StartSchedulerFactory + { + get => _startSchedulerFactory; + set => _startSchedulerFactory = Check.NotNull(value, nameof(value)); + } + private Func _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(); + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs b/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs deleted file mode 100644 index 9e48744d96..0000000000 --- a/framework/src/Volo.Abp.Quartz/Volo/Abp/Quartz/AbpQuartzPreOptions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Specialized; - -namespace Volo.Abp.Quartz -{ - public class AbpQuartzPreOptions - { - /// - /// The quartz configuration. Available properties can be found within Quartz.Impl.StdSchedulerFactory. - /// - public NameValueCollection Properties { get; set; } - /// - /// How long Quartz should wait before starting. Default: 0. - /// - public TimeSpan StartDelay { get; set; } - - public AbpQuartzPreOptions() - { - Properties = new NameValueCollection(); - StartDelay = new TimeSpan(0); - } - } -}