From 366aa2411c77ad771dcca356e7aeef049a3e1904 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Thu, 20 Jan 2022 22:54:06 +0800 Subject: [PATCH 1/2] feat(tasks): add multiple job event handlers --- aspnet-core/Directory.Build.props | 2 +- .../LINGYUN.MicroService.TaskManagement.sln | 14 ++++ .../LINGYUN.Abp.EventBus.CAP.xml | 10 +++ .../LINGYUN.Abp.EventBus.CAP.xml | 10 +++ .../AbpBackgroundTasksAbstractionsModule.cs | 28 +------ .../AbpBackgroundTasksOptions.cs | 10 +++ .../IJobCompletedNotifierProvider.cs | 9 +++ .../BackgroundTasks/IJobExceptionNotifier.cs | 9 --- .../BackgroundTasks/IJobExecutedNotifier.cs | 11 +++ .../IJobFailedNotifierProvider.cs | 9 +++ .../IJobSuccessNotifierProvider.cs | 9 +++ .../Abp/BackgroundTasks/JobEventData.cs | 21 ++--- .../JobExceptionNotificationContext.cs | 16 ---- .../BackgroundTasks/JobExecutedNotifier.cs | 67 ++++++++++++++++ .../LINGYUN/Abp/BackgroundTasks/JobInfo.cs | 2 +- .../NullJobExceptionNotifier.cs | 14 ---- ...tifier.cs => JobFailedNotifierProvider.cs} | 45 +++++------ .../Jobs/AbpBackgroundTasksJobsModule.cs | 30 +++++++ .../Jobs/BackgroundTasksConsts.cs | 6 ++ .../Jobs/HttpRequestJobBase.cs | 2 +- .../Jobs/ServiceInvocationJob.cs | 8 +- .../Quartz/QuartzJobConcurrentAdapter.cs | 6 +- .../Quartz/QuartzJobExecutorProvider.cs | 9 +-- .../Quartz/QuartzJobListener.cs | 13 ++-- .../Quartz/QuartzJobScheduler.cs | 78 +++++++++++-------- .../Quartz/IJobExecutionContextExtensions.cs | 20 ++++- ....Abp.BackgroundTasks.TaskManagement.csproj | 16 ++++ .../AbpBackgroundTasksTaskManagementModule.cs | 11 +++ .../TaskManagementJobPublisher.cs | 44 +++++++++++ .../AbpBackgroundTasksModule.cs | 8 ++ .../BackgroundTasks/BackgroundJobManager.cs | 10 +-- .../BackgroundWorkerManager.cs | 10 +-- .../Abp/BackgroundTasks/IJobPublisher.cs | 9 +++ .../Abp/BackgroundTasks/IJobScheduler.cs | 21 ++--- .../Internal/BackgroundKeepAliveJob.cs | 27 ------- .../Internal/BackgroundPollingJob.cs | 4 +- .../Internal/DefaultBackgroundWorker.cs | 48 +++--------- .../Internal/JobExecutedEvent.cs | 19 ----- .../Internal/JobNotifierEvent.cs | 32 ++++++++ .../BackgroundTasks/JobRunnableExecuter.cs | 12 +-- .../Abp/BackgroundTasks/NullJobPublisher.cs | 14 ++++ .../Abp/BackgroundTasks/NullJobScheduler.cs | 60 ++++++++++++++ .../BackgroundJobInfoCreateOrUpdateDto.cs | 2 +- .../TaskManagementDbContext.cs | 2 + ...N.Abp.TaskManagement.HttpApi.Client.csproj | 19 +++++ .../TaskManagementHttpApiClientModule.cs | 17 ++++ .../Properties/launchSettings.json | 2 +- ...ervice.RealtimeMessage.HttpApi.Host.csproj | 1 + ...ltimeMessageHttpApiHostModule.Configure.cs | 31 +++++++- .../RealtimeMessageHttpApiHostModule.cs | 2 + ...skManagementHttpApiHostModule.Configure.cs | 7 +- .../TaskManagementHttpApiHostModule.cs | 2 +- 52 files changed, 601 insertions(+), 287 deletions(-) create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobCompletedNotifierProvider.cs delete mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExecutedNotifier.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobFailedNotifierProvider.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobSuccessNotifierProvider.cs delete mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExecutedNotifier.cs delete mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs rename aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/{JobExceptionNotifier.cs => JobFailedNotifierProvider.cs} (56%) create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/BackgroundTasksConsts.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN.Abp.BackgroundTasks.TaskManagement.csproj create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/AbpBackgroundTasksTaskManagementModule.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/TaskManagementJobPublisher.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobPublisher.cs delete mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundKeepAliveJob.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobNotifierEvent.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobPublisher.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobScheduler.cs create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN/Abp/TaskManagement/TaskManagementHttpApiClientModule.cs diff --git a/aspnet-core/Directory.Build.props b/aspnet-core/Directory.Build.props index 914113047..f450474b7 100644 --- a/aspnet-core/Directory.Build.props +++ b/aspnet-core/Directory.Build.props @@ -4,7 +4,7 @@ 5.1.1 1.5.0 1.0.1 - 5.2.0 + 6.0.0 1.5.10 2.13.0 3.0.434 diff --git a/aspnet-core/LINGYUN.MicroService.TaskManagement.sln b/aspnet-core/LINGYUN.MicroService.TaskManagement.sln index f06899be8..6809b5989 100644 --- a/aspnet-core/LINGYUN.MicroService.TaskManagement.sln +++ b/aspnet-core/LINGYUN.MicroService.TaskManagement.sln @@ -40,6 +40,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks.ExceptionHandling", "modules\task-management\LINGYUN.Abp.BackgroundTasks.ExceptionHandling\LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj", "{8507BBFA-FE56-4426-BBFA-C92906CB8407}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TaskManagement.HttpApi.Client", "modules\task-management\LINGYUN.Abp.TaskManagement.HttpApi.Client\LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj", "{56C759D1-6FE6-4111-A2DB-CD65DCE82061}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.TaskManagement", "modules\task-management\LINGYUN.Abp.BackgroundTasks.TaskManagement\LINGYUN.Abp.BackgroundTasks.TaskManagement.csproj", "{7937785C-0D28-46B3-A7E7-0B592821A1F2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -94,6 +98,14 @@ Global {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Debug|Any CPU.Build.0 = Debug|Any CPU {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Release|Any CPU.ActiveCfg = Release|Any CPU {8507BBFA-FE56-4426-BBFA-C92906CB8407}.Release|Any CPU.Build.0 = Release|Any CPU + {56C759D1-6FE6-4111-A2DB-CD65DCE82061}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56C759D1-6FE6-4111-A2DB-CD65DCE82061}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56C759D1-6FE6-4111-A2DB-CD65DCE82061}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56C759D1-6FE6-4111-A2DB-CD65DCE82061}.Release|Any CPU.Build.0 = Release|Any CPU + {7937785C-0D28-46B3-A7E7-0B592821A1F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7937785C-0D28-46B3-A7E7-0B592821A1F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7937785C-0D28-46B3-A7E7-0B592821A1F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7937785C-0D28-46B3-A7E7-0B592821A1F2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -111,6 +123,8 @@ Global {4A049C32-55F2-4A5F-954A-C8A977C2D87F} = {C38EB7EF-BAE9-4129-862A-71C652B81775} {4C59F590-AA6C-4C46-8060-DA65D8305980} = {C38EB7EF-BAE9-4129-862A-71C652B81775} {8507BBFA-FE56-4426-BBFA-C92906CB8407} = {C38EB7EF-BAE9-4129-862A-71C652B81775} + {56C759D1-6FE6-4111-A2DB-CD65DCE82061} = {C38EB7EF-BAE9-4129-862A-71C652B81775} + {7937785C-0D28-46B3-A7E7-0B592821A1F2} = {385578CC-C0F1-4377-A7A2-682B8F416234} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml index d80ca3a8b..931554637 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml +++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml @@ -147,6 +147,16 @@ + + + + + + + + + + 获取事件处理类实例 diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml index d80ca3a8b..931554637 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml +++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml @@ -147,6 +147,16 @@ + + + + + + + + + + 获取事件处理类实例 diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksAbstractionsModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksAbstractionsModule.cs index 5ad3b3a60..3e349c78c 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksAbstractionsModule.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksAbstractionsModule.cs @@ -1,33 +1,7 @@ -using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections.Generic; -using Volo.Abp.Modularity; -using Volo.Abp.Reflection; +using Volo.Abp.Modularity; namespace LINGYUN.Abp.BackgroundTasks; public class AbpBackgroundTasksAbstractionsModule : AbpModule { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - AutoAddJobMonitors(context.Services); - } - - private static void AutoAddJobMonitors(IServiceCollection services) - { - var jobMonitors = new List(); - - services.OnRegistred(context => - { - if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(JobEventBase<>))) - { - jobMonitors.Add(context.ImplementationType); - } - }); - - services.Configure(options => - { - options.JobMonitors.AddIfNotContains(jobMonitors); - }); - } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs index 788102a83..3438939de 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksOptions.cs @@ -21,6 +21,10 @@ public class AbpBackgroundTasksOptions /// public IDictionary JobProviders { get; } /// + /// 启用清理任务 + /// + public bool JobCleanEnabled { get; set; } + /// /// 任务过期时间 /// 默认: 15 days /// @@ -42,6 +46,10 @@ public class AbpBackgroundTasksOptions /// public string JobCleanCronExpression { get; set; } /// + /// 启用轮询任务 + /// + public bool JobFetchEnabled { get; set; } + /// /// 每次轮询任务批次大小 /// 默认: 1000 /// @@ -64,10 +72,12 @@ public class AbpBackgroundTasksOptions public int JobFetchLockTimeOut { get; set; } public AbpBackgroundTasksOptions() { + JobFetchEnabled = true; MaxJobFetchCount = 1000; JobFetchLockTimeOut = 120; JobFetchCronExpression = "0/30 * * * * ? "; + JobCleanEnabled = true; MaxJobCleanCount = 1000; JobExpiratime = TimeSpan.FromDays(15d); JobCleanCronExpression = "0 0/10 * * * ? *"; diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobCompletedNotifierProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobCompletedNotifierProvider.cs new file mode 100644 index 000000000..b025841e7 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobCompletedNotifierProvider.cs @@ -0,0 +1,9 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.BackgroundTasks; + +public interface IJobCompletedNotifierProvider +{ + Task NotifyComplateAsync([NotNull] JobEventContext context); +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs deleted file mode 100644 index 262685cb9..000000000 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExceptionNotifier.cs +++ /dev/null @@ -1,9 +0,0 @@ -using JetBrains.Annotations; -using System.Threading.Tasks; - -namespace LINGYUN.Abp.BackgroundTasks; - -public interface IJobExceptionNotifier -{ - Task NotifyAsync([NotNull] JobExceptionNotificationContext context); -} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExecutedNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExecutedNotifier.cs new file mode 100644 index 000000000..4ae71f8ff --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobExecutedNotifier.cs @@ -0,0 +1,11 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.BackgroundTasks; + +public interface IJobExecutedNotifier +{ + Task NotifyErrorAsync([NotNull] JobEventContext context); + Task NotifySuccessAsync([NotNull] JobEventContext context); + Task NotifyComplateAsync([NotNull] JobEventContext context); +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobFailedNotifierProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobFailedNotifierProvider.cs new file mode 100644 index 000000000..610423ab7 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobFailedNotifierProvider.cs @@ -0,0 +1,9 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.BackgroundTasks; + +public interface IJobFailedNotifierProvider +{ + Task NotifyErrorAsync([NotNull] JobEventContext context); +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobSuccessNotifierProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobSuccessNotifierProvider.cs new file mode 100644 index 000000000..fd1b358ad --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobSuccessNotifierProvider.cs @@ -0,0 +1,9 @@ +using JetBrains.Annotations; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.BackgroundTasks; + +public interface IJobSuccessNotifierProvider +{ + Task NotifySuccessAsync([NotNull] JobEventContext context); +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventData.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventData.cs index a36fa6e46..3f4fbdb4b 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventData.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventData.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace LINGYUN.Abp.BackgroundTasks; @@ -9,6 +10,10 @@ public class JobEventData /// public Type Type { get; } /// + /// 任务参数 + /// + public IReadOnlyDictionary Args { get; } + /// /// 任务组别 /// public string Group { get; } @@ -49,16 +54,6 @@ public class JobEventData /// public int RepeatCount { get; set; } /// - /// 失败重试上限 - /// 默认:50 - /// - public int TryCount { get; set; } - /// - /// 最大执行次数 - /// 默认:0, 无限制 - /// - public int MaxCount { get; set; } - /// /// 运行时间 /// public DateTime RunTime { get; set; } @@ -70,21 +65,19 @@ public class JobEventData /// 下次运行时间 /// public DateTime? NextRunTime { get; set; } - /// - /// 连续失败且不会再次执行 - /// - public bool IsAbandoned { get; set; } public JobEventData( string key, Type type, string group, string name, + IReadOnlyDictionary args, Exception exception = null) { Key = key; Type = type; Group = group; Name = name; + Args = args; Exception = exception; } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs deleted file mode 100644 index 046978690..000000000 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExceptionNotificationContext.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace LINGYUN.Abp.BackgroundTasks; - -public class JobExceptionNotificationContext -{ - public JobInfo JobInfo { get; } - public Exception Exception { get; } - public JobExceptionNotificationContext( - JobInfo jobInfo, - Exception exception) - { - JobInfo = jobInfo; - Exception = exception; - } -} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExecutedNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExecutedNotifier.cs new file mode 100644 index 000000000..128a1caa9 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobExecutedNotifier.cs @@ -0,0 +1,67 @@ +using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundTasks; + +public class JobExecutedNotifier : IJobExecutedNotifier, ISingletonDependency +{ + public ILogger Logger { protected get; set; } + + public JobExecutedNotifier() + { + Logger = NullLogger.Instance; + } + + public async Task NotifyComplateAsync([NotNull] JobEventContext context) + { + var notifier = context.ServiceProvider.GetService(); + if (notifier != null) + { + try + { + await notifier.NotifyComplateAsync(context); + } + catch (Exception ex) + { + Logger.LogWarning($"An exception thow with job complete notify: {ex.Message}"); + } + } + } + + public async Task NotifyErrorAsync([NotNull] JobEventContext context) + { + var notifier = context.ServiceProvider.GetService(); + if (notifier != null) + { + try + { + await notifier.NotifyErrorAsync(context); + } + catch (Exception ex) + { + Logger.LogWarning($"An exception thow with job error notify: {ex.Message}"); + } + } + } + + public async Task NotifySuccessAsync([NotNull] JobEventContext context) + { + var notifier = context.ServiceProvider.GetService(); + if (notifier != null) + { + try + { + await notifier.NotifySuccessAsync(context); + } + catch (Exception ex) + { + Logger.LogWarning($"An exception thow with job success notify: {ex.Message}"); + } + } + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs index 34639be5b..9eb0348ac 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobInfo.cs @@ -128,7 +128,7 @@ public class JobInfo } // 重试 - if (Status == JobStatus.FailedRetry) + if (Status == JobStatus.FailedRetry && MaxTryCount > 0) { maxCount = MaxTryCount - TryCount; diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs deleted file mode 100644 index 8cc0e6e0e..000000000 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/NullJobExceptionNotifier.cs +++ /dev/null @@ -1,14 +0,0 @@ -using JetBrains.Annotations; -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; - -namespace LINGYUN.Abp.BackgroundTasks; - -[Dependency(TryRegister = true)] -public class NullJobExceptionNotifier : IJobExceptionNotifier, ISingletonDependency -{ - public Task NotifyAsync([NotNull] JobExceptionNotificationContext context) - { - return Task.CompletedTask; - } -} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobFailedNotifierProvider.cs similarity index 56% rename from aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs rename to aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobFailedNotifierProvider.cs index e8f4927fc..2d64051ab 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobFailedNotifierProvider.cs @@ -15,19 +15,18 @@ using Volo.Abp.Timing; namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling; -[Dependency(ReplaceServices = true)] -public class JobExceptionNotifier : IJobExceptionNotifier, ITransientDependency +public class JobFailedNotifierProvider : IJobFailedNotifierProvider, ITransientDependency { public const string Prefix = "exception."; public const string JobGroup = "ExceptionNotifier"; - public ILogger Logger { protected get; set; } + public ILogger Logger { protected get; set; } protected IClock Clock { get; } protected IEmailSender EmailSender { get; } protected ITemplateRenderer TemplateRenderer { get; } - public JobExceptionNotifier( + public JobFailedNotifierProvider( IClock clock, IEmailSender emailSender, ITemplateRenderer templateRenderer) @@ -36,26 +35,27 @@ public class JobExceptionNotifier : IJobExceptionNotifier, ITransientDependency EmailSender = emailSender; TemplateRenderer = templateRenderer; - Logger = NullLogger.Instance; + Logger = NullLogger.Instance; } - public virtual async Task NotifyAsync([NotNull] JobExceptionNotificationContext context) + public virtual async Task NotifyErrorAsync([NotNull] JobEventContext context) { + var eventData = context.EventData; // 异常所属分组不处理, 防止死循环 - if (string.Equals(context.JobInfo.Group, JobGroup)) + if (string.Equals(eventData.Group, JobGroup)) { - Logger.LogWarning($"There is a problem executing the job, reason: {context.Exception.Message}"); + Logger.LogWarning($"There is a problem executing the job, reason: {eventData.Exception.Message}"); return; } var notifyKey = Prefix + SendEmailJob.PropertyTo; - if (context.JobInfo.Args.TryGetValue(notifyKey, out var exceptionTo) && + if (eventData.Args.TryGetValue(notifyKey, out var exceptionTo) && exceptionTo is string to) { - var template = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyTemplate)?.ToString() ?? ""; - var content = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyBody)?.ToString() ?? ""; - var subject = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertySubject)?.ToString() ?? "From job execute exception"; - var from = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyFrom)?.ToString() ?? ""; - var errorMessage = context.Exception.GetBaseException().Message; + var template = eventData.Args.GetOrDefault(Prefix + SendEmailJob.PropertyTemplate)?.ToString() ?? ""; + var content = eventData.Args.GetOrDefault(Prefix + SendEmailJob.PropertyBody)?.ToString() ?? ""; + var subject = eventData.Args.GetOrDefault(Prefix + SendEmailJob.PropertySubject)?.ToString() ?? "From job execute exception"; + var from = eventData.Args.GetOrDefault(Prefix + SendEmailJob.PropertyFrom)?.ToString() ?? ""; + var errorMessage = eventData.Exception.GetBaseException().Message; if (template.IsNullOrWhiteSpace()) { @@ -63,22 +63,22 @@ public class JobExceptionNotifier : IJobExceptionNotifier, ITransientDependency return; } - var footer = context.JobInfo.Args.GetOrDefault("footer")?.ToString() ?? $"Copyright to LY Colin © {Clock.Now.Year}"; + var footer = eventData.Args.GetOrDefault("footer")?.ToString() ?? $"Copyright to LY Colin © {Clock.Now.Year}"; var model = new { Title = subject, - Group = context.JobInfo.Group, - Name = context.JobInfo.Name, - Id = context.JobInfo.Id, - Type = context.JobInfo.Type, + Group = eventData.Group, + Name = eventData.Name, + Id = eventData.Key, + Type = eventData.Type, Triggertime = Clock.Now.ToString("yyyy-MM-dd HH:mm:ss"), Message = errorMessage, - Tenantname = context.JobInfo.Args.GetOrDefault(nameof(IMultiTenant.TenantId)), + Tenantname = eventData.Args.GetOrDefault(nameof(IMultiTenant.TenantId)), Footer = footer, }; var globalContext = new Dictionary(); - if (context.JobInfo.Args.TryGetValue(Prefix + SendEmailJob.PropertyContext, out var ctx) && + if (eventData.Args.TryGetValue(Prefix + SendEmailJob.PropertyContext, out var ctx) && ctx is string ctxStr && !ctxStr.IsNullOrWhiteSpace()) { try @@ -87,8 +87,9 @@ public class JobExceptionNotifier : IJobExceptionNotifier, ITransientDependency } catch { } } + globalContext.AddIfNotContains(eventData.Args); - var culture = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyCulture)?.ToString() ?? CultureInfo.CurrentCulture.Name; + var culture = eventData.Args.GetOrDefault(Prefix + SendEmailJob.PropertyCulture)?.ToString() ?? CultureInfo.CurrentCulture.Name; content = await TemplateRenderer.RenderAsync( templateName: template, diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/AbpBackgroundTasksJobsModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/AbpBackgroundTasksJobsModule.cs index 8b3627f75..03bbe252e 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/AbpBackgroundTasksJobsModule.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/AbpBackgroundTasksJobsModule.cs @@ -1,4 +1,6 @@ using LINGYUN.Abp.Dapr.Client; +using LINGYUN.Abp.Dapr.Client.DynamicProxying; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Emailing; using Volo.Abp.Http.Client; using Volo.Abp.Modularity; @@ -12,6 +14,23 @@ namespace LINGYUN.Abp.BackgroundTasks.Jobs; [DependsOn(typeof(AbpDaprClientModule))] public class AbpBackgroundTasksJobsModule : AbpModule { + protected const string DontWrapResultField = "_AbpDontWrapResult"; + + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(options => + { + options.ProxyClientBuildActions.Add((remoteService, builder) => + { + builder.ConfigureHttpClient(client => + { + // 后台作业一般都是内部调用, 不需要包装结果 + client.DefaultRequestHeaders.TryAddWithoutValidation(DontWrapResultField, "true"); + }); + }); + }); + } + public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => @@ -23,5 +42,16 @@ public class AbpBackgroundTasksJobsModule : AbpModule options.AddProvider(DefaultJobNames.ServiceInvocationJob); options.AddProvider(DefaultJobNames.HttpRequestJob); }); + + Configure(options => + { + options.ProxyRequestActions.Add((remoteService, request) => + { + // 后台作业一般都是内部调用, 不需要包装结果 + request.Headers.TryAddWithoutValidation(DontWrapResultField, "true"); + }); + }); + + context.Services.AddHttpClient(BackgroundTasksConsts.DefaultHttpClient); } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/BackgroundTasksConsts.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/BackgroundTasksConsts.cs new file mode 100644 index 000000000..8e6d81cb6 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/BackgroundTasksConsts.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.BackgroundTasks.Jobs; + +internal static class BackgroundTasksConsts +{ + public const string DefaultHttpClient = "_AbpBackgroundTasks_Client"; +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/HttpRequestJobBase.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/HttpRequestJobBase.cs index e5e7fcdd8..47629c27f 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/HttpRequestJobBase.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/HttpRequestJobBase.cs @@ -81,7 +81,7 @@ public abstract class HttpRequestJobBase var clientFactory = context.GetRequiredService(); var client = clientName.IsNullOrWhiteSpace() - ? clientFactory.CreateClient() + ? clientFactory.CreateClient(BackgroundTasksConsts.DefaultHttpClient) : clientFactory.CreateClient(clientName); var response = await client.SendAsync(request); diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ServiceInvocationJob.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ServiceInvocationJob.cs index 69799b5be..7f10f61c6 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ServiceInvocationJob.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ServiceInvocationJob.cs @@ -57,13 +57,7 @@ public class ServiceInvocationJob : IJobRunnable null); } - Guid? tenantId = null; - if (context.TryGetString(PropertyTenant, out var tenant) && - Guid.TryParse(tenant, out var converTenant)) - { - tenantId = converTenant; - } - + context.TryGetMultiTenantId(PropertyTenant, out var tenantId); var currentTenant = context.GetRequiredService(); using (currentTenant.Change(tenantId)) { diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobConcurrentAdapter.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobConcurrentAdapter.cs index 1fde4e3c0..1ba4519fc 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobConcurrentAdapter.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobConcurrentAdapter.cs @@ -1,4 +1,4 @@ -using System; +using Microsoft.Extensions.DependencyInjection; using Quartz; namespace LINGYUN.Abp.BackgroundTasks.Quartz; @@ -7,8 +7,8 @@ namespace LINGYUN.Abp.BackgroundTasks.Quartz; public class QuartzJobConcurrentAdapter : QuartzJobSimpleAdapter where TJobRunnable : IJobRunnable { - public QuartzJobConcurrentAdapter(IServiceProvider serviceProvider) - : base(serviceProvider) + public QuartzJobConcurrentAdapter(IServiceScopeFactory serviceScopeFactory) + : base(serviceScopeFactory) { } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs index 2b2b6e388..966be21e9 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobExecutorProvider.cs @@ -37,16 +37,9 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD return null; } - var adapterType = typeof(QuartzJobSimpleAdapter<>); - - // 注释, 通过触发器监听锁定 - //if (job.LockTimeOut > 0) - //{ - // adapterType = typeof(QuartzJobConcurrentAdapter<>); - //} - if (!typeof(IJob).IsAssignableFrom(jobType)) { + var adapterType = typeof(QuartzJobSimpleAdapter<>); jobType = adapterType.MakeGenericType(jobType); } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobListener.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobListener.cs index 585e7d3bc..0a9bcc5ca 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobListener.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobListener.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Quartz; using Quartz.Listener; using System; +using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -67,7 +68,8 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency jobId, context.JobDetail.JobType, context.JobDetail.Key.Group, - context.JobDetail.Key.Name) + context.JobDetail.Key.Name, + context.MergedJobDataMap.ToImmutableDictionary()) { Result = context.Result?.ToString() }; @@ -120,6 +122,7 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency jobType, context.JobDetail.Key.Group, context.JobDetail.Key.Name, + context.MergedJobDataMap.ToImmutableDictionary(), jobException) { Status = JobStatus.Running @@ -140,11 +143,9 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency { jobEventData.Result = context.Result?.ToString(); } - var tenantIdString = context.GetString(nameof(IMultiTenant.TenantId)); - if (Guid.TryParse(tenantIdString, out var tenantId)) - { - jobEventData.TenantId = tenantId; - } + + context.TryGetMultiTenantId(out var tenantId); + jobEventData.TenantId = tenantId; var eventContext = new JobEventContext( scope.ServiceProvider, diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobScheduler.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobScheduler.cs index 3113e94ef..891af8266 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobScheduler.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobScheduler.cs @@ -1,12 +1,17 @@ using Quartz; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace LINGYUN.Abp.BackgroundTasks.Quartz; [Dependency(ReplaceServices = true)] -public class QuartzJobScheduler : IJobScheduler, ISingletonDependency +[ExposeServices( + typeof(IJobScheduler), + typeof(IJobPublisher), + typeof(QuartzJobScheduler))] +public class QuartzJobScheduler : IJobScheduler, IJobPublisher, ISingletonDependency { protected IJobStore JobStore { get; } protected IScheduler Scheduler { get; } @@ -25,28 +30,33 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency QuartzJobExecutor = quartzJobExecutor; } - public virtual async Task ExistsAsync(JobInfo job) + public virtual async Task ExistsAsync(JobInfo job, CancellationToken cancellationToken = default) { - return await Scheduler.CheckExists(BuildJobKey(job)); + return await Scheduler.CheckExists(BuildJobKey(job), cancellationToken); } - public virtual async Task PauseAsync(JobInfo job) + public virtual async Task PauseAsync(JobInfo job, CancellationToken cancellationToken = default) { var jobKey = BuildJobKey(job); - if (await Scheduler.CheckExists(jobKey)) + if (await Scheduler.CheckExists(jobKey, cancellationToken)) { - var triggers = await Scheduler.GetTriggersOfJob(jobKey); + var triggers = await Scheduler.GetTriggersOfJob(jobKey, cancellationToken); foreach (var trigger in triggers) { - await Scheduler.PauseTrigger(trigger.Key); + await Scheduler.PauseTrigger(trigger.Key, cancellationToken); } } } - public virtual async Task QueueAsync(JobInfo job) + public virtual async Task PublishAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return await QueueAsync(job, cancellationToken); + } + + public virtual async Task QueueAsync(JobInfo job, CancellationToken cancellationToken = default) { var jobKey = BuildJobKey(job); - if (await Scheduler.CheckExists(jobKey)) + if (await Scheduler.CheckExists(jobKey, cancellationToken)) { return false; } @@ -63,12 +73,12 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency return false; } - await Scheduler.ScheduleJob(jobDetail, jobTrigger); + await Scheduler.ScheduleJob(jobDetail, jobTrigger, cancellationToken); - return await Scheduler.CheckExists(jobTrigger.Key); + return await Scheduler.CheckExists(jobTrigger.Key, cancellationToken); } - public virtual async Task QueuesAsync(IEnumerable jobs) + public virtual async Task QueuesAsync(IEnumerable jobs, CancellationToken cancellationToken = default) { var jobDictionary = new Dictionary>(); foreach (var job in jobs) @@ -88,78 +98,78 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency jobDictionary[jobDetail] = new ITrigger[] { jobTrigger }; } - await Scheduler.ScheduleJobs(jobDictionary, true); + await Scheduler.ScheduleJobs(jobDictionary, true, cancellationToken); } - public virtual async Task RemoveAsync(JobInfo job) + public virtual async Task RemoveAsync(JobInfo job, CancellationToken cancellationToken = default) { var jobKey = BuildJobKey(job); - if (!await Scheduler.CheckExists(jobKey)) + if (!await Scheduler.CheckExists(jobKey, cancellationToken)) { return false; } - var triggers = await Scheduler.GetTriggersOfJob(jobKey); + var triggers = await Scheduler.GetTriggersOfJob(jobKey, cancellationToken); foreach (var trigger in triggers) { - await Scheduler.PauseTrigger(trigger.Key); + await Scheduler.PauseTrigger(trigger.Key, cancellationToken); } - await Scheduler.DeleteJob(jobKey); + await Scheduler.DeleteJob(jobKey, cancellationToken); - return !await Scheduler.CheckExists(jobKey); + return !await Scheduler.CheckExists(jobKey, cancellationToken); } - public virtual async Task ResumeAsync(JobInfo job) + public virtual async Task ResumeAsync(JobInfo job, CancellationToken cancellationToken = default) { var jobKey = BuildJobKey(job); - if (await Scheduler.CheckExists(jobKey)) + if (await Scheduler.CheckExists(jobKey, cancellationToken)) { - var triggers = await Scheduler.GetTriggersOfJob(jobKey); + var triggers = await Scheduler.GetTriggersOfJob(jobKey, cancellationToken); foreach (var trigger in triggers) { - await Scheduler.ResumeTrigger(trigger.Key); + await Scheduler.ResumeTrigger(trigger.Key, cancellationToken); } } } - public virtual async Task ShutdownAsync() + public virtual async Task ShutdownAsync(CancellationToken cancellationToken = default) { - await StopAsync(); + await StopAsync(cancellationToken); - await Scheduler.Shutdown(true); + await Scheduler.Shutdown(true, cancellationToken); return Scheduler.IsShutdown; } - public virtual async Task StartAsync() + public virtual async Task StartAsync(CancellationToken cancellationToken = default) { if (Scheduler.InStandbyMode) { - await Scheduler.Start(); + await Scheduler.Start(cancellationToken); } return Scheduler.InStandbyMode; } - public virtual async Task StopAsync() + public virtual async Task StopAsync(CancellationToken cancellationToken = default) { if (!Scheduler.InStandbyMode) { //等待任务运行完成 - await Scheduler.Standby(); + await Scheduler.Standby(cancellationToken); } return !Scheduler.InStandbyMode; } - public virtual async Task TriggerAsync(JobInfo job) + public virtual async Task TriggerAsync(JobInfo job, CancellationToken cancellationToken = default) { var jobKey = BuildJobKey(job); - if (!await Scheduler.CheckExists(jobKey)) + if (!await Scheduler.CheckExists(jobKey, cancellationToken)) { - await QueueAsync(job); + await QueueAsync(job, cancellationToken); } else { - await Scheduler.TriggerJob(jobKey); + await Scheduler.TriggerJob(jobKey, cancellationToken); } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/Quartz/IJobExecutionContextExtensions.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/Quartz/IJobExecutionContextExtensions.cs index 3d46e4614..8772ba717 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/Quartz/IJobExecutionContextExtensions.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/Quartz/IJobExecutionContextExtensions.cs @@ -1,4 +1,5 @@ -using System; +using LINGYUN.Abp.BackgroundTasks; +using System; namespace Quartz; @@ -24,4 +25,21 @@ public static class IJobExecutionContextExtensions return value; } + + public static bool TryGetMultiTenantId(this IJobExecutionContext context, out Guid? tenantId) + { + return context.TryGetMultiTenantId(nameof(JobInfo.TenantId), out tenantId); + } + + public static bool TryGetMultiTenantId(this IJobExecutionContext context, string multiTenancyKey, out Guid? tenantId) + { + tenantId = null; + var tenantUUIdString = context.GetString(multiTenancyKey); + if (Guid.TryParse(tenantUUIdString, out var tenantUUId)) + { + tenantId = tenantUUId; + return true; + } + return false; + } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN.Abp.BackgroundTasks.TaskManagement.csproj b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN.Abp.BackgroundTasks.TaskManagement.csproj new file mode 100644 index 000000000..489936699 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN.Abp.BackgroundTasks.TaskManagement.csproj @@ -0,0 +1,16 @@ + + + + + + + netstandard2.0 + + + + + + + + + diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/AbpBackgroundTasksTaskManagementModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/AbpBackgroundTasksTaskManagementModule.cs new file mode 100644 index 000000000..c02842762 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/AbpBackgroundTasksTaskManagementModule.cs @@ -0,0 +1,11 @@ +using LINGYUN.Abp.TaskManagement.HttpApi.Client; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.BackgroundTasks.TaskManagement; + +[DependsOn(typeof(AbpBackgroundTasksModule))] +[DependsOn(typeof(TaskManagementHttpApiClientModule))] +public class AbpBackgroundTasksTaskManagementModule : AbpModule +{ + +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/TaskManagementJobPublisher.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/TaskManagementJobPublisher.cs new file mode 100644 index 000000000..074301dc9 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.TaskManagement/LINGYUN/Abp/BackgroundTasks/TaskManagement/TaskManagementJobPublisher.cs @@ -0,0 +1,44 @@ +using LINGYUN.Abp.TaskManagement; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundTasks.TaskManagement; + +public class TaskManagementJobPublisher : IJobPublisher, ITransientDependency +{ + protected IBackgroundJobInfoAppService BackgroundJobAppService { get; } + + public TaskManagementJobPublisher( + IBackgroundJobInfoAppService backgroundJobAppService) + { + BackgroundJobAppService = backgroundJobAppService; + } + + public async virtual Task PublishAsync(JobInfo job, CancellationToken cancellationToken = default) + { + var input = new BackgroundJobInfoCreateDto + { + Cron = job.Cron, + MaxCount = job.MaxCount, + MaxTryCount = job.MaxTryCount, + Args = new ExtraPropertyDictionary(job.Args), + BeginTime = job.BeginTime, + Description = job.Description, + EndTime = job.EndTime, + Group = job.Group, + Interval = job.Interval, + Type = job.Type, + JobType = job.JobType, + LockTimeOut = job.LockTimeOut, + IsEnabled = true, + Name = job.Name, + Priority = job.Priority, + }; + + await BackgroundJobAppService.CreateAsync(input); + + return true; + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksModule.cs index b4c0718a6..3e46426d3 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksModule.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/AbpBackgroundTasksModule.cs @@ -1,6 +1,7 @@ using LINGYUN.Abp.BackgroundTasks.Internal; using LINGYUN.Abp.BackgroundTasks.Localization; using Microsoft.Extensions.DependencyInjection; +using System.Collections.Generic; using Volo.Abp.Auditing; using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundWorkers; @@ -39,5 +40,12 @@ public class AbpBackgroundTasksModule : AbpModule .Add("en") .AddVirtualJson("/LINGYUN/Abp/BackgroundTasks/Localization/Resources"); }); + + Configure(options => + { + options.JobMonitors.AddIfNotContains(typeof(JobExecutedEvent)); + options.JobMonitors.AddIfNotContains(typeof(JobLogEvent)); + options.JobMonitors.AddIfNotContains(typeof(JobNotifierEvent)); + }); } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs index e36d1576d..11904df52 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundJobManager.cs @@ -16,7 +16,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency { protected IClock Clock { get; } protected IJobStore JobStore { get; } - protected IJobScheduler JobScheduler { get; } + protected IJobPublisher JobPublisher { get; } protected ICurrentTenant CurrentTenant { get; } protected IGuidGenerator GuidGenerator { get; } protected IJsonSerializer JsonSerializer { get; } @@ -24,7 +24,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency public BackgroundJobManager( IClock clock, IJobStore jobStore, - IJobScheduler jobScheduler, + IJobPublisher jobPublisher, ICurrentTenant currentTenant, IGuidGenerator guidGenerator, IJsonSerializer jsonSerializer, @@ -32,7 +32,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency { Clock = clock; JobStore = jobStore; - JobScheduler = jobScheduler; + JobPublisher = jobPublisher; CurrentTenant = currentTenant; GuidGenerator = guidGenerator; JsonSerializer = jsonSerializer; @@ -79,8 +79,8 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency // 存储状态 await JobStore.StoreAsync(jobInfo); - // 手动入队 - await JobScheduler.QueueAsync(jobInfo); + // 发布作业 + await JobPublisher.PublishAsync(jobInfo); return jobInfo.Id; } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerManager.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerManager.cs index f11d640c3..fb40f5135 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerManager.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerManager.cs @@ -11,14 +11,14 @@ namespace LINGYUN.Abp.BackgroundTasks; public class BackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDependency { protected IJobStore JobStore { get; } - protected IJobScheduler JobScheduler { get; } + protected IJobPublisher JobPublisher { get; } public BackgroundWorkerManager( IJobStore jobStore, - IJobScheduler jobScheduler) + IJobPublisher jobPublisher) { JobStore = jobStore; - JobScheduler = jobScheduler; + JobPublisher = jobPublisher; } public async Task AddAsync(IBackgroundWorker worker) @@ -37,8 +37,8 @@ public class BackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDepen // 存储状态 await JobStore.StoreAsync(jobInfo); - // 手动入队 - await JobScheduler.QueueAsync(jobInfo); + // 发布作业 + await JobPublisher.PublishAsync(jobInfo); } public Task StartAsync(CancellationToken cancellationToken = default) diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobPublisher.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobPublisher.cs new file mode 100644 index 000000000..b27bbda18 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobPublisher.cs @@ -0,0 +1,9 @@ +using System.Threading; +using System.Threading.Tasks; + +namespace LINGYUN.Abp.BackgroundTasks; + +public interface IJobPublisher +{ + Task PublishAsync(JobInfo job, CancellationToken cancellationToken = default); +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobScheduler.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobScheduler.cs index 4ec76be9a..d383bd515 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobScheduler.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/IJobScheduler.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using System.Collections.Generic; +using System.Threading; namespace LINGYUN.Abp.BackgroundTasks; /// @@ -12,61 +13,61 @@ public interface IJobScheduler /// /// /// - Task QueueAsync(JobInfo job); + Task QueueAsync(JobInfo job, CancellationToken cancellationToken = default); /// /// 任务入队 /// /// /// - Task QueuesAsync(IEnumerable jobs); + Task QueuesAsync(IEnumerable jobs, CancellationToken cancellationToken = default); /// /// 任务是否存在 /// /// /// /// - Task ExistsAsync(JobInfo job); + Task ExistsAsync(JobInfo job, CancellationToken cancellationToken = default); /// /// 触发任务 /// /// /// /// - Task TriggerAsync(JobInfo job); + Task TriggerAsync(JobInfo job, CancellationToken cancellationToken = default); /// /// 暂停任务 /// /// /// /// - Task PauseAsync(JobInfo job); + Task PauseAsync(JobInfo job, CancellationToken cancellationToken = default); /// /// 恢复暂停的任务 /// /// /// /// - Task ResumeAsync(JobInfo job); + Task ResumeAsync(JobInfo job, CancellationToken cancellationToken = default); /// /// 移除任务 /// /// /// /// - Task RemoveAsync(JobInfo job); + Task RemoveAsync(JobInfo job, CancellationToken cancellationToken = default); /// /// 启动任务协调器 /// /// - Task StartAsync(); + Task StartAsync(CancellationToken cancellationToken = default); /// /// 停止任务协调器 /// /// - Task StopAsync(); + Task StopAsync(CancellationToken cancellationToken = default); /// /// 释放任务协调器 /// /// - Task ShutdownAsync(); + Task ShutdownAsync(CancellationToken cancellationToken = default); } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundKeepAliveJob.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundKeepAliveJob.cs deleted file mode 100644 index bc2c7ecef..000000000 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundKeepAliveJob.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using System.Linq; -using System.Threading.Tasks; -using Volo.Abp.Auditing; - -namespace LINGYUN.Abp.BackgroundTasks.Internal; - -[DisableAuditing] -public class BackgroundKeepAliveJob : IJobRunnable -{ - public virtual async Task ExecuteAsync(JobRunnableContext context) - { - var store = context.ServiceProvider.GetRequiredService(); - - // TODO: 如果积压有大量周期性任务, 可能后面的队列无法被检索到 - var periodJobs = await store.GetAllPeriodTasksAsync(); - - if (!periodJobs.Any()) - { - return; - } - - var jobScheduler = context.ServiceProvider.GetRequiredService(); - - await jobScheduler.QueuesAsync(periodJobs); - } -} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundPollingJob.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundPollingJob.cs index 211a8d9ff..0e1fff084 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundPollingJob.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/BackgroundPollingJob.cs @@ -27,11 +27,11 @@ public class BackgroundPollingJob : IJobRunnable return; } - var jobScheduler = context.ServiceProvider.GetRequiredService(); + var jobPublisher = context.ServiceProvider.GetRequiredService(); foreach (var job in waitingJobs) { - await jobScheduler.QueueAsync(job); + await jobPublisher.PublishAsync(job); } } } diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs index 7317666c1..89e75e449 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/DefaultBackgroundWorker.cs @@ -10,65 +10,41 @@ namespace LINGYUN.Abp.BackgroundTasks.Internal; internal class DefaultBackgroundWorker : BackgroundService { private readonly IJobStore _jobStore; - private readonly IJobScheduler _jobScheduler; + private readonly IJobPublisher _jobPublisher; private readonly AbpBackgroundTasksOptions _options; public DefaultBackgroundWorker( IJobStore jobStore, - IJobScheduler jobScheduler, + IJobPublisher jobPublisher, IOptions options) { _jobStore = jobStore; - _jobScheduler = jobScheduler; + _jobPublisher = jobPublisher; _options = options.Value; } protected async override Task ExecuteAsync(CancellationToken stoppingToken) { - // 仅轮询宿主端 await QueuePollingJob(); await QueueCleaningJob(); - - // 周期性任务改为手动入队 - // await QueueKeepAliveJob(); - } - - private async Task QueueKeepAliveJob() - { - var keepAliveJob = BuildKeepAliveJobInfo(); - await _jobScheduler.QueueAsync(keepAliveJob); } private async Task QueuePollingJob() { - var pollingJob = BuildPollingJobInfo(); - await _jobScheduler.QueueAsync(pollingJob); + if (_options.JobFetchEnabled) + { + var pollingJob = BuildPollingJobInfo(); + await _jobPublisher.PublishAsync(pollingJob); + } } private async Task QueueCleaningJob() { - var cleaningJob = BuildCleaningJobInfo(); - await _jobScheduler.QueueAsync(cleaningJob); - } - - private JobInfo BuildKeepAliveJobInfo() - { - return new JobInfo + if (_options.JobCleanEnabled) { - Id = "KeepAlive", - Name = nameof(BackgroundKeepAliveJob), - Group = "KeepAlive", - Description = "Add periodic tasks", - Args = new Dictionary(), - Status = JobStatus.Running, - BeginTime = DateTime.Now, - CreationTime = DateTime.Now, - JobType = JobType.Once, - Priority = JobPriority.High, - MaxCount = 1, - Interval = 30, - Type = typeof(BackgroundKeepAliveJob).AssemblyQualifiedName, - }; + var cleaningJob = BuildCleaningJobInfo(); + await _jobPublisher.PublishAsync(cleaningJob); + } } private JobInfo BuildPollingJobInfo() diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs index 115dc26e6..91722c18d 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; @@ -64,9 +63,6 @@ public class JobExecutedEvent : JobEventBase, ITransientDepend job.NextRunTime = null; await RemoveJobAsync(context, job); } - - // 每次重试发布异常通知 - await NotifierAsync(context, job); } else { @@ -94,21 +90,6 @@ public class JobExecutedEvent : JobEventBase, ITransientDepend await jobScheduler.RemoveAsync(jobInfo); } - private async Task NotifierAsync(JobEventContext context, JobInfo jobInfo) - { - try - { - var notifier = context.ServiceProvider.GetRequiredService(); - var exceptionContext = new JobExceptionNotificationContext(jobInfo, context.EventData.Exception); - - await notifier.NotifyAsync(exceptionContext); - } - catch (Exception ex) - { - Logger.LogWarning($"An exception thow with job exception notify: {ex.Message}"); - } - } - private string GetExceptionMessage(Exception exception) { if (exception.InnerException != null) diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobNotifierEvent.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobNotifierEvent.cs new file mode 100644 index 000000000..0ad968f39 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobNotifierEvent.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundTasks.Internal; + +public class JobNotifierEvent : JobEventBase, ITransientDependency +{ + protected async override Task OnJobAfterExecutedAsync(JobEventContext context) + { + try + { + var notifier = context.ServiceProvider.GetRequiredService(); + if (context.EventData.Exception != null) + { + await notifier.NotifyErrorAsync(context); + } + else + { + await notifier.NotifySuccessAsync(context); + } + + await notifier.NotifyComplateAsync(context); + } + catch (Exception ex) + { + Logger.LogWarning($"An exception thow with job notify: {ex.Message}"); + } + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobRunnableExecuter.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobRunnableExecuter.cs index 9e92ded39..c16edc041 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobRunnableExecuter.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobRunnableExecuter.cs @@ -6,18 +6,14 @@ using Volo.Abp.MultiTenancy; namespace LINGYUN.Abp.BackgroundTasks; -public class JobRunnableExecuter : IJobRunnableExecuter, ISingletonDependency +public class JobRunnableExecuter : IJobRunnableExecuter, ITransientDependency { public async virtual Task ExecuteAsync(JobRunnableContext context) { - Guid? tenantId = null; - if (context.JobData.TryGetValue(nameof(IMultiTenant.TenantId), out var tenant) && - Guid.TryParse(tenant?.ToString(), out var tid)) - { - tenantId = tid; - } - var currentTenant = context.ServiceProvider.GetRequiredService(); + + context.TryGetMultiTenantId(out var tenantId); + using (currentTenant.Change(tenantId)) { await InternalExecuteAsync(context); diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobPublisher.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobPublisher.cs new file mode 100644 index 000000000..af4517105 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobPublisher.cs @@ -0,0 +1,14 @@ +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundTasks; + +[Dependency(TryRegister = true)] +public class NullJobPublisher : IJobPublisher, ISingletonDependency +{ + public Task PublishAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobScheduler.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobScheduler.cs new file mode 100644 index 000000000..0f5051d5e --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/NullJobScheduler.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BackgroundTasks; + +[Dependency(TryRegister = true)] +public class NullJobScheduler : IJobScheduler, ISingletonDependency +{ + public Task ExistsAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } + + public Task PauseAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task QueueAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } + + public Task QueuesAsync(IEnumerable jobs, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task RemoveAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } + + public Task ResumeAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } + + public Task ShutdownAsync(CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } + + public Task StartAsync(CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } + + public Task StopAsync(CancellationToken cancellationToken = default) + { + return Task.FromResult(false); + } + + public Task TriggerAsync(JobInfo job, CancellationToken cancellationToken = default) + { + return Task.CompletedTask; + } +} diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateOrUpdateDto.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateOrUpdateDto.cs index 16874189a..3d3eb804f 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateOrUpdateDto.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateOrUpdateDto.cs @@ -10,7 +10,7 @@ public abstract class BackgroundJobInfoCreateOrUpdateDto /// /// 是否启用 /// - public bool IsEnabled { get; set; } + public bool IsEnabled { get; set; } = true; /// /// 任务参数 /// diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContext.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContext.cs index a6d1f99ac..87fb41052 100644 --- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContext.cs +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContext.cs @@ -1,8 +1,10 @@ using Microsoft.EntityFrameworkCore; +using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; namespace LINGYUN.Abp.TaskManagement.EntityFrameworkCore; +[ConnectionStringName(TaskManagementDbProperties.ConnectionStringName)] public class TaskManagementDbContext : AbpDbContext, ITaskManagementDbContext { public TaskManagementDbContext( diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj new file mode 100644 index 000000000..35c510af2 --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj @@ -0,0 +1,19 @@ + + + + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN/Abp/TaskManagement/TaskManagementHttpApiClientModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN/Abp/TaskManagement/TaskManagementHttpApiClientModule.cs new file mode 100644 index 000000000..850fcd0ea --- /dev/null +++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.HttpApi.Client/LINGYUN/Abp/TaskManagement/TaskManagementHttpApiClientModule.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.TaskManagement.HttpApi.Client; + +[DependsOn(typeof(TaskManagementApplicationContractsModule))] +[DependsOn(typeof(AbpHttpClientModule))] +public class TaskManagementHttpApiClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(TaskManagementApplicationContractsModule).Assembly, + TaskManagementRemoteServiceConsts.RemoteServiceName); + } +} \ No newline at end of file diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Properties/launchSettings.json b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Properties/launchSettings.json index 731195696..ceb66ec05 100644 --- a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Properties/launchSettings.json +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Properties/launchSettings.json @@ -14,7 +14,7 @@ "launchBrowser": false, "applicationUrl": "http://127.0.0.1:30010", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Production" + "ASPNETCORE_ENVIRONMENT": "Development" } } } diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj index 1e029e6c9..dbd822994 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/LY.MicroService.RealtimeMessage.HttpApi.Host.csproj @@ -43,6 +43,7 @@ + diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.Configure.cs index 4442fd402..d871bd169 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.Configure.cs @@ -11,6 +11,7 @@ using LINGYUN.Abp.Serilog.Enrichers.UniqueId; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.StackExchangeRedis; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -31,14 +32,15 @@ using Volo.Abp.Json; using Volo.Abp.Json.SystemTextJson; using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; +using Volo.Abp.Timing; using Volo.Abp.VirtualFileSystem; - using HangfireDashboardOptions = Hangfire.DashboardOptions; namespace LY.MicroService.RealtimeMessage; public partial class RealtimeMessageHttpApiHostModule { + protected static string[] PrefixTokenQueryStrings = new [] { "/signalr-hubs", "/hangfire" }; private void PreConfigureApp() { AbpSerilogEnrichersConsts.ApplicationName = "MessageService"; @@ -292,13 +294,34 @@ public partial class RealtimeMessageHttpApiHostModule var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && - (path.StartsWithSegments("/signalr-hubs"))) + PrefixTokenQueryStrings.Any(prefix => path.StartsWithSegments(prefix))) { - // Read the token out of the query string + // 解决仪表板自定义授权问题 context.Token = accessToken; + + var clock = context.HttpContext.RequestServices.GetRequiredService(); + var protectedProvider = context.HttpContext.RequestServices.GetRequiredService(); + var protector = protectedProvider.CreateProtector("_hangfire_tk"); + var tokenCookies = protector.Protect(accessToken); + context.HttpContext.Response.Cookies.Append( + "_hangfire_tk", + tokenCookies, + new CookieOptions + { + Expires = clock.Now.AddMinutes(10) + }); + } + + if (context.Token.IsNullOrWhiteSpace() && + context.Request.Cookies.TryGetValue("_hangfire_tk", out var protectedToken)) + { + var protectedProvider = context.HttpContext.RequestServices.GetRequiredService(); + var protector = protectedProvider.CreateProtector("_hangfire_tk"); + context.Token = protector.Unprotect(protectedToken); } + return Task.CompletedTask; - } + }, }; }); diff --git a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs index 5976629b5..9c1725423 100644 --- a/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.RealtimeMessage.HttpApi.Host/RealtimeMessageHttpApiHostModule.cs @@ -2,6 +2,7 @@ using LINGYUN.Abp.AspNetCore.HttpOverrides; using LINGYUN.Abp.AuditLogging.Elasticsearch; using LINGYUN.Abp.BackgroundJobs.Hangfire; +using LINGYUN.Abp.BackgroundWorkers.Hangfire; using LINGYUN.Abp.Data.DbMigrator; using LINGYUN.Abp.EventBus.CAP; using LINGYUN.Abp.ExceptionHandling.Notifications; @@ -56,6 +57,7 @@ namespace LY.MicroService.RealtimeMessage typeof(AbpAspNetCoreAuthenticationJwtBearerModule), typeof(AbpHangfireMySqlStorageModule), typeof(AbpBackgroundJobsHangfireModule), + typeof(AbpBackgroundWorkersHangfireModule), typeof(AbpBackgroundWorkersModule), typeof(AbpIMSignalRModule), typeof(AbpNotificationsSmsModule), diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs index f562f6796..30cc4edb3 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.Configure.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.ExceptionHandling; +using DotNetCore.CAP; +using LINGYUN.Abp.ExceptionHandling; using LINGYUN.Abp.ExceptionHandling.Emailing; using LINGYUN.Abp.Serilog.Enrichers.Application; using LINGYUN.Abp.Serilog.Enrichers.UniqueId; @@ -10,10 +11,10 @@ using Microsoft.Extensions.Caching.StackExchangeRedis; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; +using Quartz; using StackExchange.Redis; using System; using System.Collections.Generic; -using System.Collections.Specialized; using System.Text.Encodings.Web; using System.Text.Unicode; using Volo.Abp; @@ -26,8 +27,6 @@ using Volo.Abp.Localization; using Volo.Abp.MultiTenancy; using Volo.Abp.Quartz; using Volo.Abp.VirtualFileSystem; -using Quartz; -using DotNetCore.CAP; namespace LY.MicroService.TaskManagement; diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs index dc3a8282f..014641541 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs @@ -94,7 +94,7 @@ public partial class TaskManagementHttpApiHostModule : AbpModule ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); // 开发取消权限检查 - // context.Services.AddAlwaysAllowAuthorization(); + context.Services.AddAlwaysAllowAuthorization(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) From b96bd342363959388d72703909c3712c5dce745b Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Thu, 20 Jan 2022 22:58:58 +0800 Subject: [PATCH 2/2] fix: authorization --- .../TaskManagementHttpApiHostModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs index 014641541..dc3a8282f 100644 --- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs +++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs @@ -94,7 +94,7 @@ public partial class TaskManagementHttpApiHostModule : AbpModule ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment()); // 开发取消权限检查 - context.Services.AddAlwaysAllowAuthorization(); + // context.Services.AddAlwaysAllowAuthorization(); } public override void OnApplicationInitialization(ApplicationInitializationContext context)