From 2f90d90c69dfda37ac6a56e5216c60a72450a44c Mon Sep 17 00:00:00 2001
From: cKey <35512826+colinin@users.noreply.github.com>
Date: Tue, 5 Apr 2022 17:11:39 +0800
Subject: [PATCH] feat: the job scheduler does not need to centralize
processing
---
.../AbpBackgroundTasksOptions.cs | 4 +
.../LINGYUN/Abp/BackgroundTasks/JobInfo.cs | 4 +
.../Quartz/QuartzJobExecutorProvider.cs | 2 +
.../Quartz/QuartzTriggerListener.cs | 30 ++-
.../TaskManagementJobPublisher.cs | 8 +-
.../BackgroundTasks/BackgroundJobManager.cs | 6 +-
.../BackgroundWorkerAdapter.cs | 8 -
.../BackgroundWorkerManager.cs | 20 +-
.../Internal/DefaultBackgroundWorker.cs | 2 +
.../BackgroundJobInfoCreateDto.cs | 3 +
.../BackgroundJobInfoAppService.cs | 14 +-
.../TaskManagement/BackgroundJobInfoConsts.cs | 1 +
.../Abp/TaskManagement/BackgroundJobInfo.cs | 7 +-
.../TaskManagement/BackgroundJobManager.cs | 9 +-
.../Abp/TaskManagement/BackgroundJobStore.cs | 19 +-
.../IBackgroundJobInfoRepository.cs | 6 +
.../EfCoreBackgroundJobInfoRepository.cs | 16 +-
...agementDbContextModelCreatingExtensions.cs | 3 +
.../LINGYUN.Abp.Webhooks.csproj | 2 +-
.../LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs | 4 +-
.../BackgroundWorker/WebhookSenderJob.cs | 18 +-
.../LINGYUN/Abp/Webhooks/WebhookDefinition.cs | 10 -
.../LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs | 5 +
...odeName-With-BackgroundJobInfo.Designer.cs | 213 ++++++++++++++++++
...d-Field-NodeName-With-BackgroundJobInfo.cs | 27 +++
...agementMigrationsDbContextModelSnapshot.cs | 5 +
...ice.WebhooksManagement.HttpApi.Host.csproj | 14 +-
...ksManagementHttpApiHostModule.Configure.cs | 40 ++++
.../WebhooksManagementHttpApiHostModule.cs | 9 +-
.../appsettings.Development.json | 15 ++
30 files changed, 452 insertions(+), 72 deletions(-)
create mode 100644 aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.Designer.cs
create mode 100644 aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.cs
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 3438939de..2efcb8f5f 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
@@ -70,6 +70,10 @@ public class AbpBackgroundTasksOptions
/// 轮询任务也属于一个后台任务, 需要对每一次轮询加锁,防止重复任务入库
///
public int JobFetchLockTimeOut { get; set; }
+ ///
+ /// 指定运行节点
+ ///
+ public string NodeName { get; set; }
public AbpBackgroundTasksOptions()
{
JobFetchEnabled = true;
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 46f7ab78c..98842ec17 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
@@ -109,6 +109,10 @@ public class JobInfo
/// 0或更小不生效
///
public int LockTimeOut { get; set; }
+ ///
+ /// 指定运行节点
+ ///
+ public string NodeName { get; set; }
public int GetCanBeTriggered()
{
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 26acdca4e..b05185607 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
@@ -47,6 +47,8 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
var jobBuilder = JobBuilder.Create(jobType)
.WithIdentity(KeyBuilder.CreateJobKey(job))
.WithDescription(job.Description);
+ // 多节点任务需要
+ jobBuilder.UsingJobData(nameof(JobInfo.NodeName), job.NodeName);
// 查询任务需要
jobBuilder.UsingJobData(nameof(JobInfo.Id), job.Id);
// 有些场景需要
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzTriggerListener.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzTriggerListener.cs
index 8bd37d8d7..29c095e47 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzTriggerListener.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzTriggerListener.cs
@@ -1,8 +1,12 @@
-using Quartz;
+using Microsoft.Extensions.Options;
+using Quartz;
using Quartz.Listener;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
+using System;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
namespace LINGYUN.Abp.BackgroundTasks.Quartz;
@@ -12,12 +16,19 @@ public class QuartzTriggerListener : TriggerListenerSupport, ISingletonDependenc
public override string Name => "QuartzTriggerListener";
+ public ILogger Logger { protected get; set; }
+
+ protected AbpBackgroundTasksOptions Options { get; }
protected IJobLockProvider JobLockProvider { get; }
public QuartzTriggerListener(
- IJobLockProvider jobLockProvider)
+ IJobLockProvider jobLockProvider,
+ IOptions options)
{
JobLockProvider = jobLockProvider;
+ Options = options.Value;
+
+ Logger = NullLogger.Instance;
}
public override async Task VetoJobExecution(
@@ -25,12 +36,25 @@ public class QuartzTriggerListener : TriggerListenerSupport, ISingletonDependenc
IJobExecutionContext context,
CancellationToken cancellationToken = default)
{
+ if (!Options.NodeName.IsNullOrWhiteSpace())
+ {
+ context.MergedJobDataMap.TryGetValue(nameof(JobInfo.NodeName), out var jobNode);
+ if (!Equals(Options.NodeName, jobNode))
+ {
+ Logger.LogDebug("the job does not belong to the current node and will be ignored by the scheduler.");
+ return true;
+ }
+ }
context.MergedJobDataMap.TryGetValue(nameof(JobInfo.Id), out var jobId);
context.MergedJobDataMap.TryGetValue(nameof(JobInfo.LockTimeOut), out var lockTime);
if (jobId != null && lockTime != null && int.TryParse(lockTime.ToString(), out var time) && time > 0)
{
// 传递令牌将清除本次锁, 那并无意义
- return !await JobLockProvider.TryLockAsync(NormalizeKey(context, jobId), time);
+ if (!await JobLockProvider.TryLockAsync(NormalizeKey(context, jobId), time))
+ {
+ Logger.LogDebug("The exclusive job is already in use by another scheduler. Ignore this schedule.");
+ return true;
+ }
}
return false;
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
index 074301dc9..e1ff1f704 100644
--- 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
@@ -1,4 +1,5 @@
using LINGYUN.Abp.TaskManagement;
+using Microsoft.Extensions.Options;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
@@ -8,12 +9,15 @@ namespace LINGYUN.Abp.BackgroundTasks.TaskManagement;
public class TaskManagementJobPublisher : IJobPublisher, ITransientDependency
{
+ protected AbpBackgroundTasksOptions Options { get; }
protected IBackgroundJobInfoAppService BackgroundJobAppService { get; }
public TaskManagementJobPublisher(
- IBackgroundJobInfoAppService backgroundJobAppService)
+ IBackgroundJobInfoAppService backgroundJobAppService,
+ IOptions options)
{
BackgroundJobAppService = backgroundJobAppService;
+ Options = options.Value;
}
public async virtual Task PublishAsync(JobInfo job, CancellationToken cancellationToken = default)
@@ -34,7 +38,9 @@ public class TaskManagementJobPublisher : IJobPublisher, ITransientDependency
LockTimeOut = job.LockTimeOut,
IsEnabled = true,
Name = job.Name,
+ Source = job.Source,
Priority = job.Priority,
+ NodeName = Options.NodeName,
};
await BackgroundJobAppService.CreateAsync(input);
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 a81f67921..28f92653a 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
@@ -20,6 +20,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency
protected ICurrentTenant CurrentTenant { get; }
protected IGuidGenerator GuidGenerator { get; }
protected IJsonSerializer JsonSerializer { get; }
+ protected AbpBackgroundTasksOptions TasksOptions { get; }
protected AbpBackgroundJobOptions Options { get; }
public BackgroundJobManager(
IClock clock,
@@ -28,7 +29,8 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency
ICurrentTenant currentTenant,
IGuidGenerator guidGenerator,
IJsonSerializer jsonSerializer,
- IOptions options)
+ IOptions options,
+ IOptions taskOptions)
{
Clock = clock;
JobStore = jobStore;
@@ -37,6 +39,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency
GuidGenerator = guidGenerator;
JsonSerializer = jsonSerializer;
Options = options.Value;
+ TasksOptions = taskOptions.Value;
}
public virtual async Task EnqueueAsync(
@@ -74,6 +77,7 @@ public class BackgroundJobManager : IBackgroundJobManager, ITransientDependency
CreationTime = Clock.Now,
// 确保不会被轮询入队
Status = JobStatus.None,
+ NodeName = TasksOptions.NodeName,
Type = typeof(BackgroundJobAdapter).AssemblyQualifiedName,
};
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerAdapter.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerAdapter.cs
index 4797acaca..e45e9210f 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerAdapter.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/BackgroundWorkerAdapter.cs
@@ -4,18 +4,13 @@ using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DynamicProxy;
-using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
-using Volo.Abp.Timing;
namespace LINGYUN.Abp.BackgroundTasks;
public class BackgroundWorkerAdapter : BackgroundWorkerBase, IBackgroundWorkerRunnable
where TWorker : IBackgroundWorker
{
- protected IClock Clock => LazyServiceProvider.LazyGetRequiredService();
- protected ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService();
-
private readonly MethodInfo _doWorkAsyncMethod;
private readonly MethodInfo _doWorkMethod;
@@ -70,12 +65,10 @@ public class BackgroundWorkerAdapter : BackgroundWorkerBase, IBackgroun
return new JobInfo
{
Id = workerType.FullName,
- TenantId = CurrentTenant.Id,
Name = workerType.FullName,
Group = "BackgroundWorkers",
Priority = JobPriority.Normal,
Source = JobSource.System,
- BeginTime = Clock.Now,
Args = jobArgs,
Description = "From the framework background workers",
JobType = JobType.Persistent,
@@ -83,7 +76,6 @@ public class BackgroundWorkerAdapter : BackgroundWorkerBase, IBackgroun
MaxCount = 0,
// TODO: 可配置
MaxTryCount = 10,
- CreationTime = Clock.Now,
// 确保不会被轮询入队
Status = JobStatus.None,
Type = typeof(BackgroundWorkerAdapter).AssemblyQualifiedName,
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 fb40f5135..366aae3da 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
@@ -1,24 +1,36 @@
-using System;
+using Microsoft.Extensions.Options;
+using System;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.Timing;
namespace LINGYUN.Abp.BackgroundTasks;
[Dependency(ReplaceServices = true)]
public class BackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDependency
{
+ protected IClock Clock { get; }
protected IJobStore JobStore { get; }
protected IJobPublisher JobPublisher { get; }
+ protected ICurrentTenant CurrentTenant { get; }
+ protected AbpBackgroundTasksOptions Options { get; }
public BackgroundWorkerManager(
+ IClock clock,
IJobStore jobStore,
- IJobPublisher jobPublisher)
+ IJobPublisher jobPublisher,
+ ICurrentTenant currentTenant,
+ IOptions options)
{
+ Clock = clock;
JobStore = jobStore;
JobPublisher = jobPublisher;
+ CurrentTenant = currentTenant;
+ Options = options.Value;
}
public async Task AddAsync(IBackgroundWorker worker)
@@ -34,6 +46,10 @@ public class BackgroundWorkerManager : IBackgroundWorkerManager, ISingletonDepen
return;
}
+ jobInfo.NodeName = Options.NodeName;
+ jobInfo.BeginTime = Clock.Now;
+ jobInfo.CreationTime = Clock.Now;
+ jobInfo.TenantId = CurrentTenant.Id;
// 存储状态
await JobStore.StoreAsync(jobInfo);
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 a8920f34e..b38030783 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
@@ -64,6 +64,7 @@ internal class DefaultBackgroundWorker : BackgroundService
Priority = JobPriority.High,
Source = JobSource.System,
LockTimeOut = _options.JobFetchLockTimeOut,
+ NodeName = _options.NodeName,
Type = typeof(BackgroundPollingJob).AssemblyQualifiedName,
};
}
@@ -84,6 +85,7 @@ internal class DefaultBackgroundWorker : BackgroundService
JobType = JobType.Period,
Priority = JobPriority.High,
Source = JobSource.System,
+ NodeName = _options.NodeName,
Type = typeof(BackgroundCleaningJob).AssemblyQualifiedName,
};
}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateDto.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateDto.cs
index a391aa228..2706086d6 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateDto.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application.Contracts/LINGYUN/Abp/TaskManagement/BackgroundJobInfoCreateDto.cs
@@ -25,6 +25,9 @@ public class BackgroundJobInfoCreateDto : BackgroundJobInfoCreateOrUpdateDto
[Required]
[DynamicStringLength(typeof(BackgroundJobInfoConsts), nameof(BackgroundJobInfoConsts.MaxTypeLength))]
public string Type { get; set; }
+
+ [DynamicStringLength(typeof(BackgroundJobInfoConsts), nameof(BackgroundJobInfoConsts.MaxNodeNameLength))]
+ public string NodeName { get; set; }
///
/// 开始时间
///
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs
index 01f54f01a..c3a36539c 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs
@@ -1,6 +1,7 @@
using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.TaskManagement.Permissions;
using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@@ -13,15 +14,18 @@ namespace LINGYUN.Abp.TaskManagement;
[Authorize(TaskManagementPermissions.BackgroundJobs.Default)]
public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBackgroundJobInfoAppService
{
+ protected AbpBackgroundTasksOptions Options { get; }
protected BackgroundJobManager BackgroundJobManager { get; }
protected IBackgroundJobInfoRepository BackgroundJobInfoRepository { get; }
public BackgroundJobInfoAppService(
BackgroundJobManager backgroundJobManager,
- IBackgroundJobInfoRepository backgroundJobInfoRepository)
+ IBackgroundJobInfoRepository backgroundJobInfoRepository,
+ IOptions options)
{
BackgroundJobManager = backgroundJobManager;
BackgroundJobInfoRepository = backgroundJobInfoRepository;
+ Options = options.Value;
}
[Authorize(TaskManagementPermissions.BackgroundJobs.Create)]
@@ -47,16 +51,14 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
input.Source,
input.MaxCount,
input.MaxTryCount,
+ input.NodeName ?? Options.NodeName,
CurrentTenant.Id);
UpdateByInput(backgroundJobInfo, input);
- await BackgroundJobInfoRepository.InsertAsync(backgroundJobInfo, autoSave: true);
+ await BackgroundJobManager.CreateAsync(backgroundJobInfo);
- if (backgroundJobInfo.IsEnabled && backgroundJobInfo.JobType == JobType.Period)
- {
- await BackgroundJobManager.QueueAsync(backgroundJobInfo);
- }
+ await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map(backgroundJobInfo);
}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/BackgroundJobInfoConsts.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/BackgroundJobInfoConsts.cs
index 733823f4c..1d3ad97da 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/BackgroundJobInfoConsts.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain.Shared/LINGYUN/Abp/TaskManagement/BackgroundJobInfoConsts.cs
@@ -5,6 +5,7 @@ public static class BackgroundJobInfoConsts
public static int MaxCronLength { get; set; } = 50;
public static int MaxNameLength { get; set; } = 100;
public static int MaxGroupLength { get; set; } = 50;
+ public static int MaxNodeNameLength { get; set; } = 128;
public static int MaxTypeLength { get; set; } = 1000;
public static int MaxDescriptionLength { get; set; } = 255;
public static int MaxResultLength { get; set; } = 1000;
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfo.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfo.cs
index bb202421c..6c7342c94 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfo.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfo.cs
@@ -107,7 +107,10 @@ public class BackgroundJobInfo : AuditedAggregateRoot, IMultiTenant
/// 连续失败且不会再次执行
///
public virtual bool IsAbandoned { get; set; }
-
+ ///
+ /// 指定作业运行节点
+ ///
+ public virtual string NodeName { get; protected set; }
protected BackgroundJobInfo() { }
public BackgroundJobInfo(
@@ -122,6 +125,7 @@ public class BackgroundJobInfo : AuditedAggregateRoot, IMultiTenant
JobSource source = JobSource.None,
int maxCount = 0,
int maxTryCount = 50,
+ string nodeName = null,
Guid? tenantId = null) : base(id)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name), BackgroundJobInfoConsts.MaxNameLength);
@@ -134,6 +138,7 @@ public class BackgroundJobInfo : AuditedAggregateRoot, IMultiTenant
MaxCount = maxCount;
MaxTryCount = maxTryCount;
+ NodeName = Check.Length(nodeName, nameof(nodeName), BackgroundJobInfoConsts.MaxNodeNameLength);
TenantId = tenantId;
Status = JobStatus.Running;
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobManager.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobManager.cs
index 4dd9a07f4..19ea64aab 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobManager.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobManager.cs
@@ -1,7 +1,6 @@
using LINGYUN.Abp.BackgroundTasks;
-using System.Threading.Tasks;
using System.Collections.Generic;
-using Volo.Abp;
+using System.Threading.Tasks;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow;
@@ -34,12 +33,6 @@ public class BackgroundJobManager : DomainService
if (jobInfo.IsEnabled && jobInfo.JobType == JobType.Period)
{
var job = ObjectMapper.Map(jobInfo);
- if (await JobScheduler.ExistsAsync(job))
- {
- throw new BusinessException(TaskManagementErrorCodes.JobNameAlreadyExists)
- .WithData("Group", job.Group)
- .WithData("Name", job.Name);
- }
UnitOfWorkManager.Current.OnCompleted(async () =>
{
await JobScheduler.QueueAsync(job);
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs
index b48cd20a7..8c6df46ab 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobStore.cs
@@ -1,9 +1,9 @@
using LINGYUN.Abp.BackgroundTasks;
+using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
-using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
@@ -19,28 +19,32 @@ public class BackgroundJobStore : IJobStore, ITransientDependency
protected IBackgroundJobInfoRepository JobInfoRepository { get; }
protected IBackgroundJobLogRepository JobLogRepository { get; }
+ protected AbpBackgroundTasksOptions Options { get; }
+
public BackgroundJobStore(
IObjectMapper objectMapper,
ICurrentTenant currentTenant,
IBackgroundJobInfoRepository jobInfoRepository,
- IBackgroundJobLogRepository jobLogRepository)
+ IBackgroundJobLogRepository jobLogRepository,
+ IOptions options)
{
ObjectMapper = objectMapper;
CurrentTenant = currentTenant;
JobInfoRepository = jobInfoRepository;
JobLogRepository = jobLogRepository;
+ Options = options.Value;
}
public async virtual Task> GetAllPeriodTasksAsync(CancellationToken cancellationToken = default)
{
- var jobInfos = await JobInfoRepository.GetAllPeriodTasksAsync(cancellationToken);
+ var jobInfos = await JobInfoRepository.GetAllPeriodTasksAsync(Options.NodeName, cancellationToken);
return ObjectMapper.Map, List>(jobInfos);
}
public async virtual Task> GetWaitingListAsync(int maxResultCount, CancellationToken cancellationToken = default)
{
- var jobInfos = await JobInfoRepository.GetWaitingListAsync(maxResultCount, cancellationToken);
+ var jobInfos = await JobInfoRepository.GetWaitingListAsync(Options.NodeName, maxResultCount, cancellationToken);
return ObjectMapper.Map, List>(jobInfos);
}
@@ -142,9 +146,10 @@ public class BackgroundJobStore : IJobStore, ITransientDependency
CancellationToken cancellationToken = default)
{
var jobs = await JobInfoRepository.GetExpiredJobsAsync(
- maxResultCount,
- jobExpiratime,
- cancellationToken);
+ Options.NodeName,
+ maxResultCount,
+ jobExpiratime,
+ cancellationToken);
await JobInfoRepository.DeleteManyAsync(jobs, cancellationToken: cancellationToken);
}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/IBackgroundJobInfoRepository.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/IBackgroundJobInfoRepository.cs
index 603d66c1f..f02f59794 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/IBackgroundJobInfoRepository.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/IBackgroundJobInfoRepository.cs
@@ -27,11 +27,13 @@ public interface IBackgroundJobInfoRepository : IRepository
/// 获取过期任务列表
///
+ ///
///
///
///
///
Task> GetExpiredJobsAsync(
+ string nodeName,
int maxResultCount,
TimeSpan jobExpiratime,
CancellationToken cancellationToken = default);
@@ -39,16 +41,20 @@ public interface IBackgroundJobInfoRepository : IRepository
+ ///
///
Task> GetAllPeriodTasksAsync(
+ string nodeName,
CancellationToken cancellationToken = default);
///
/// 获取等待入队的任务列表
///
+ ///
///
///
///
Task> GetWaitingListAsync(
+ string nodeName,
int maxResultCount,
CancellationToken cancellationToken = default);
///
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs
index 073a75e92..9b86a16e4 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs
@@ -69,12 +69,14 @@ public class EfCoreBackgroundJobInfoRepository :
Result = x.Result,
TriggerCount = x.TriggerCount,
TryCount = x.TryCount,
- Type = x.Type
+ Type = x.Type,
+ NodeName = x.NodeName,
})
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task> GetExpiredJobsAsync(
+ string nodeName,
int maxResultCount,
TimeSpan jobExpiratime,
CancellationToken cancellationToken = default)
@@ -82,6 +84,7 @@ public class EfCoreBackgroundJobInfoRepository :
var expiratime = Clock.Now - jobExpiratime;
return await (await GetDbSetAsync())
+ .Where(x => x.NodeName == nodeName)
.Where(x => x.Status == JobStatus.Completed &&
DateTime.Compare(x.LastRunTime.Value, expiratime) <= 0)
.OrderBy(x => x.CreationTime)
@@ -89,11 +92,14 @@ public class EfCoreBackgroundJobInfoRepository :
.ToListAsync(GetCancellationToken(cancellationToken));
}
- public virtual async Task> GetAllPeriodTasksAsync(CancellationToken cancellationToken = default)
+ public virtual async Task> GetAllPeriodTasksAsync(
+ string nodeName,
+ CancellationToken cancellationToken = default)
{
var status = new JobStatus[] { JobStatus.Running, JobStatus.FailedRetry };
return await (await GetDbSetAsync())
+ .Where(x => x.NodeName == nodeName)
.Where(x => x.IsEnabled && !x.IsAbandoned)
.Where(x => x.JobType == JobType.Period && status.Contains(x.Status))
.Where(x => (x.MaxCount == 0 || x.TriggerCount < x.MaxCount) || (x.MaxTryCount == 0 || x.TryCount < x.MaxTryCount))
@@ -116,12 +122,16 @@ public class EfCoreBackgroundJobInfoRepository :
.ToListAsync(GetCancellationToken(cancellationToken));
}
- public virtual async Task> GetWaitingListAsync(int maxResultCount, CancellationToken cancellationToken = default)
+ public virtual async Task> GetWaitingListAsync(
+ string nodeName,
+ int maxResultCount,
+ CancellationToken cancellationToken = default)
{
var now = Clock.Now;
var status = new JobStatus[] { JobStatus.Running, JobStatus.FailedRetry };
return await (await GetDbSetAsync())
+ .Where(x => x.NodeName == nodeName)
.Where(x => x.IsEnabled && !x.IsAbandoned)
.Where(x => x.JobType != JobType.Period && status.Contains(x.Status))
.Where(x => (x.MaxCount == 0 || x.TriggerCount < x.MaxCount) || (x.MaxTryCount == 0 || x.TryCount < x.MaxTryCount))
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContextModelCreatingExtensions.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContextModelCreatingExtensions.cs
index 36c6ca547..2a677e917 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContextModelCreatingExtensions.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/TaskManagementDbContextModelCreatingExtensions.cs
@@ -47,6 +47,9 @@ public static class TaskManagementDbContextModelCreatingExtensions
b.Property(p => p.Result)
.HasColumnName(nameof(BackgroundJobInfo.Result))
.HasMaxLength(BackgroundJobInfoConsts.MaxResultLength);
+ b.Property(p => p.NodeName)
+ .HasColumnName(nameof(BackgroundJobInfo.NodeName))
+ .HasMaxLength(BackgroundJobInfoConsts.MaxNodeNameLength);
b.Property(p => p.Args)
.HasColumnName(nameof(BackgroundJobInfo.Args))
.HasConversion(new ExtraPropertiesValueConverter(b.Metadata.ClrType))
diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN.Abp.Webhooks.csproj b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN.Abp.Webhooks.csproj
index 2cd64673f..ca6031c7a 100644
--- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN.Abp.Webhooks.csproj
+++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN.Abp.Webhooks.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs
index 84798d8d2..0e66d8f81 100644
--- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs
+++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/AbpWebhooksModule.cs
@@ -9,9 +9,7 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Webhooks;
-//[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))]
-// 防止未引用实现无法发布到后台作业
-[DependsOn(typeof(AbpBackgroundJobsModule))]
+[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))]
[DependsOn(typeof(AbpFeaturesModule))]
[DependsOn(typeof(AbpGuidsModule))]
[DependsOn(typeof(AbpHttpClientModule))]
diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs
index b411e3a84..4d18cb209 100644
--- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs
+++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/BackgroundWorker/WebhookSenderJob.cs
@@ -11,7 +11,6 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker
public class WebhookSenderJob : AsyncBackgroundJob, ITransientDependency
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
- private readonly IWebhookDefinitionManager _webhookDefinitionManager;
private readonly IWebhookSubscriptionManager _webhookSubscriptionManager;
private readonly IWebhookSendAttemptStore _webhookSendAttemptStore;
private readonly IWebhookSender _webhookSender;
@@ -20,14 +19,12 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker
public WebhookSenderJob(
IUnitOfWorkManager unitOfWorkManager,
- IWebhookDefinitionManager webhookDefinitionManager,
IWebhookSubscriptionManager webhookSubscriptionManager,
IWebhookSendAttemptStore webhookSendAttemptStore,
IWebhookSender webhookSender,
IOptions options)
{
_unitOfWorkManager = unitOfWorkManager;
- _webhookDefinitionManager = webhookDefinitionManager;
_webhookSubscriptionManager = webhookSubscriptionManager;
_webhookSendAttemptStore = webhookSendAttemptStore;
_webhookSender = webhookSender;
@@ -36,13 +33,11 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker
public override async Task ExecuteAsync(WebhookSenderArgs args)
{
- var webhookDefinition = _webhookDefinitionManager.Get(args.WebhookName);
-
- if (webhookDefinition.TryOnce)
+ if (args.TryOnce)
{
try
{
- await SendWebhook(args, webhookDefinition);
+ await SendWebhook(args);
}
catch (Exception e)
{
@@ -52,11 +47,11 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker
}
else
{
- await SendWebhook(args, webhookDefinition);
+ await SendWebhook(args);
}
}
- private async Task SendWebhook(WebhookSenderArgs args, WebhookDefinition webhookDefinition)
+ private async Task SendWebhook(WebhookSenderArgs args)
{
if (args.WebhookEventId == default)
{
@@ -68,7 +63,7 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker
return;
}
- if (!webhookDefinition.TryOnce)
+ if (!args.TryOnce)
{
var sendAttemptCount = await _webhookSendAttemptStore.GetSendAttemptCountAsync(
args.TenantId,
@@ -76,8 +71,7 @@ namespace LINGYUN.Abp.Webhooks.BackgroundWorker
args.WebhookSubscriptionId
);
- if ((webhookDefinition.MaxSendAttemptCount > 0 && sendAttemptCount > webhookDefinition.MaxSendAttemptCount) ||
- sendAttemptCount > _options.MaxSendAttemptCount)
+ if (sendAttemptCount > _options.MaxSendAttemptCount)
{
return;
}
diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs
index 1c1461e8a..88f3a074d 100644
--- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs
+++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookDefinition.cs
@@ -11,16 +11,6 @@ namespace LINGYUN.Abp.Webhooks
///
public string Name { get; }
- ///
- /// Tries to send webhook only one time without checking to send attempt count
- ///
- public bool TryOnce { get; set; }
-
- ///
- /// Defined maximum number of sending times
- ///
- public int MaxSendAttemptCount { get; set; }
-
///
/// Display name of the webhook.
/// Optional.
diff --git a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs
index cb30acbf9..7910ba0b1 100644
--- a/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs
+++ b/aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookSenderArgs.cs
@@ -46,6 +46,11 @@ namespace LINGYUN.Abp.Webhooks
///
public IDictionary Headers { get; set; }
+ ///
+ /// Tries to send webhook only one time without checking to send attempt count
+ ///
+ public bool TryOnce { get; set; }
+
///
/// True: It sends the exact same data as the parameter to clients.
///
diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.Designer.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.Designer.cs
new file mode 100644
index 000000000..2170291ca
--- /dev/null
+++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.Designer.cs
@@ -0,0 +1,213 @@
+//
+using System;
+using LY.MicroService.TaskManagement.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Volo.Abp.EntityFrameworkCore;
+
+#nullable disable
+
+namespace LY.MicroService.TaskManagement.Migrations
+{
+ [DbContext(typeof(TaskManagementMigrationsDbContext))]
+ [Migration("20220405072809_Add-Field-NodeName-With-BackgroundJobInfo")]
+ partial class AddFieldNodeNameWithBackgroundJobInfo
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
+ .HasAnnotation("ProductVersion", "6.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobInfo", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("varchar(255)");
+
+ b.Property("Args")
+ .HasColumnType("longtext")
+ .HasColumnName("Args");
+
+ b.Property("BeginTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("varchar(40)")
+ .HasColumnName("ConcurrencyStamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("CreationTime");
+
+ b.Property("CreatorId")
+ .HasColumnType("char(36)")
+ .HasColumnName("CreatorId");
+
+ b.Property("Cron")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)")
+ .HasColumnName("Cron");
+
+ b.Property("Description")
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)")
+ .HasColumnName("Description");
+
+ b.Property("EndTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("longtext")
+ .HasColumnName("ExtraProperties");
+
+ b.Property("Group")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)")
+ .HasColumnName("Group");
+
+ b.Property("Interval")
+ .HasColumnType("int");
+
+ b.Property("IsAbandoned")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsEnabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("JobType")
+ .HasColumnType("int");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("datetime(6)")
+ .HasColumnName("LastModificationTime");
+
+ b.Property("LastModifierId")
+ .HasColumnType("char(36)")
+ .HasColumnName("LastModifierId");
+
+ b.Property("LastRunTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("LockTimeOut")
+ .HasColumnType("int");
+
+ b.Property("MaxCount")
+ .HasColumnType("int");
+
+ b.Property("MaxTryCount")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)")
+ .HasColumnName("Name");
+
+ b.Property("NextRunTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("NodeName")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("NodeName");
+
+ b.Property("Priority")
+ .HasColumnType("int");
+
+ b.Property("Result")
+ .HasMaxLength(1000)
+ .HasColumnType("varchar(1000)")
+ .HasColumnName("Result");
+
+ b.Property("Source")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasDefaultValue(-1)
+ .HasColumnName("Source");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.Property("TriggerCount")
+ .HasColumnType("int");
+
+ b.Property("TryCount")
+ .HasColumnType("int");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("varchar(1000)")
+ .HasColumnName("Type");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Name", "Group");
+
+ b.ToTable("TK_BackgroundJobs", (string)null);
+ });
+
+ modelBuilder.Entity("LINGYUN.Abp.TaskManagement.BackgroundJobLog", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("Exception")
+ .HasMaxLength(2000)
+ .HasColumnType("varchar(2000)")
+ .HasColumnName("Exception");
+
+ b.Property("JobGroup")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)")
+ .HasColumnName("JobGroup");
+
+ b.Property("JobId")
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)")
+ .HasColumnName("JobId");
+
+ b.Property("JobName")
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)")
+ .HasColumnName("JobName");
+
+ b.Property("JobType")
+ .HasMaxLength(1000)
+ .HasColumnType("varchar(1000)")
+ .HasColumnName("JobType");
+
+ b.Property("Message")
+ .HasMaxLength(1000)
+ .HasColumnType("varchar(1000)")
+ .HasColumnName("Message");
+
+ b.Property("RunTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("TenantId")
+ .HasColumnType("char(36)")
+ .HasColumnName("TenantId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("JobGroup", "JobName");
+
+ b.ToTable("TK_BackgroundJobLogs", (string)null);
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.cs
new file mode 100644
index 000000000..58d6dd3c2
--- /dev/null
+++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/20220405072809_Add-Field-NodeName-With-BackgroundJobInfo.cs
@@ -0,0 +1,27 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace LY.MicroService.TaskManagement.Migrations
+{
+ public partial class AddFieldNodeNameWithBackgroundJobInfo : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "NodeName",
+ table: "TK_BackgroundJobs",
+ type: "varchar(128)",
+ maxLength: 128,
+ nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "NodeName",
+ table: "TK_BackgroundJobs");
+ }
+ }
+}
diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/TaskManagementMigrationsDbContextModelSnapshot.cs b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/TaskManagementMigrationsDbContextModelSnapshot.cs
index 1b6f44954..e77b0f616 100644
--- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/TaskManagementMigrationsDbContextModelSnapshot.cs
+++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/Migrations/TaskManagementMigrationsDbContextModelSnapshot.cs
@@ -111,6 +111,11 @@ namespace LY.MicroService.TaskManagement.Migrations
b.Property("NextRunTime")
.HasColumnType("datetime(6)");
+ b.Property("NodeName")
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)")
+ .HasColumnName("NodeName");
+
b.Property("Priority")
.HasColumnType("int");
diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj
index 78cda36e2..a2659d4f1 100644
--- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj
+++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/LY.MicroService.WebhooksManagement.HttpApi.Host.csproj
@@ -34,6 +34,7 @@
+
@@ -57,11 +58,14 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs
index ddb24ddb0..e8269ad2b 100644
--- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs
+++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.Configure.cs
@@ -1,4 +1,5 @@
using DotNetCore.CAP;
+using LINGYUN.Abp.BackgroundTasks;
using LINGYUN.Abp.Dapr.Client.DynamicProxying;
using LINGYUN.Abp.ExceptionHandling;
using LINGYUN.Abp.ExceptionHandling.Emailing;
@@ -15,8 +16,10 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
+using Quartz;
using StackExchange.Redis;
using System;
+using System.Collections.Generic;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using Volo.Abp;
@@ -28,6 +31,7 @@ using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
+using Volo.Abp.Quartz;
using Volo.Abp.Threading;
using Volo.Abp.VirtualFileSystem;
@@ -76,6 +80,34 @@ public partial class WebhooksManagementHttpApiHostModule
});
}
+ private void PreConfigureQuartz(IConfiguration configuration)
+ {
+ PreConfigure(options =>
+ {
+ // 如果使用持久化存储, 则配置quartz持久层
+ if (configuration.GetSection("Quartz:UsePersistentStore").Get())
+ {
+ var settings = configuration.GetSection("Quartz:Properties").Get>();
+ if (settings != null)
+ {
+ foreach (var setting in settings)
+ {
+ options.Properties[setting.Key] = setting.Value;
+ }
+ }
+
+ options.Configurator += (config) =>
+ {
+ config.UsePersistentStore(store =>
+ {
+ store.UseProperties = false;
+ store.UseJsonSerializer();
+ });
+ };
+ }
+ });
+ }
+
private void ConfigureDbContext()
{
// 配置Ef
@@ -90,6 +122,14 @@ public partial class WebhooksManagementHttpApiHostModule
});
}
+ private void ConfigureBackgroundTasks()
+ {
+ Configure(options =>
+ {
+ options.NodeName = ApplicationName;
+ });
+ }
+
private void ConfigureJsonSerializer()
{
// 解决某些不支持类型的序列化
diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs
index fe0d5379e..6ecd3954e 100644
--- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs
+++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/WebhooksManagementHttpApiHostModule.cs
@@ -1,12 +1,15 @@
using DotNetCore.CAP;
using LINGYUN.Abp.AspNetCore.Mvc.Wrapper;
using LINGYUN.Abp.AuditLogging.Elasticsearch;
+using LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
+using LINGYUN.Abp.BackgroundTasks.Quartz;
using LINGYUN.Abp.EventBus.CAP;
using LINGYUN.Abp.ExceptionHandling.Emailing;
using LINGYUN.Abp.LocalizationManagement.EntityFrameworkCore;
using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.Serilog.Enrichers.Application;
using LINGYUN.Abp.Serilog.Enrichers.UniqueId;
+using LINGYUN.Abp.TaskManagement.EntityFrameworkCore;
using LINGYUN.Abp.Webhooks.Identity;
using LINGYUN.Abp.Webhooks.Saas;
using LINGYUN.Abp.WebhooksManagement;
@@ -42,6 +45,9 @@ namespace LY.MicroService.WebhooksManagement;
typeof(WebhooksManagementEntityFrameworkCoreModule),
typeof(AbpWebhooksIdentityModule),
typeof(AbpWebhooksSaasModule),
+ typeof(AbpBackgroundTasksQuartzModule),
+ typeof(AbpBackgroundTasksExceptionHandlingModule),
+ typeof(TaskManagementEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpEmailingExceptionHandlingModule),
@@ -68,6 +74,7 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule
PreConfigureApp();
PreConfigureFeature();
PreConfigureCAP(configuration);
+ PreConfigureQuartz(configuration);
}
public override void ConfigureServices(ServiceConfigurationContext context)
@@ -79,6 +86,7 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule
ConfigureDbContext();
ConfigureLocalization();
ConfigureJsonSerializer();
+ ConfigureBackgroundTasks();
ConfigureExceptionHandling();
ConfigureVirtualFileSystem();
ConfigureCaching(configuration);
@@ -89,7 +97,6 @@ public partial class WebhooksManagementHttpApiHostModule : AbpModule
ConfigureDistributedLock(context.Services, configuration);
ConfigureSeedWorker(context.Services, hostingEnvironment.IsDevelopment());
ConfigureSecurity(context.Services, configuration, hostingEnvironment.IsDevelopment());
-
context.Services.AddAlwaysAllowAuthorization();
}
diff --git a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json
index 4a816c0c1..57f18945f 100644
--- a/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json
+++ b/aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/appsettings.Development.json
@@ -13,6 +13,7 @@
"ConnectionStrings": {
"Default": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"WebhooksManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
+ "TaskManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpSaas": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpFeatureManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
"AbpPermissionManagement": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
@@ -60,6 +61,20 @@
"VirtualHost": "/"
}
},
+ "Quartz": {
+ "UsePersistentStore": false,
+ "Properties": {
+ "quartz.jobStore.dataSource": "tkm",
+ "quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz",
+ "quartz.jobStore.driverDelegateType": "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz",
+ "quartz.dataSource.tkm.connectionString": "Server=127.0.0.1;Database=Platform;User Id=root;Password=123456",
+ "quartz.dataSource.tkm.connectionStringName": "TaskManagement",
+ "quartz.dataSource.tkm.provider": "MySqlConnector",
+ "quartz.jobStore.clustered": "true",
+ "quartz.serializer.type": "json",
+ "quartz.scheduler.instanceName": "webhook"
+ }
+ },
"Redis": {
"Configuration": "127.0.0.1,defaultDatabase=10",
"InstanceName": "LINGYUN.Abp.Application"