From 27b5c69d127baf86414bfce52f7812d90d7adf8c Mon Sep 17 00:00:00 2001
From: cKey <35512826+colinin@users.noreply.github.com>
Date: Tue, 11 Jan 2022 19:40:58 +0800
Subject: [PATCH 1/2] fix(tasks): the lock task does not block the listener
from running
---
.../Abp/BackgroundTasks/IJobLockProvider.cs | 19 ++++++
.../Quartz/AbpBackgroundTasksQuartzModule.cs | 2 +
.../Quartz/QuartzJobExecutorProvider.cs | 10 +--
.../Quartz/QuartzJobListener.cs | 22 +++++--
.../Quartz/QuartzTriggerListener.cs | 56 +++++++++++++++++
.../LINGYUN.Abp.BackgroundTasks.csproj | 1 +
.../Abp/BackgroundTasks/JobLockProvider.cs | 61 +++++++++++++++++++
.../BackgroundTasks/JobRunnableExecuter.cs | 30 +--------
.../BackgroundJobInfoAppService.cs | 6 +-
...Service.TaskManagement.HttpApi.Host.csproj | 1 +
.../TaskManagementHttpApiHostModule.cs | 2 +
11 files changed, 171 insertions(+), 39 deletions(-)
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobLockProvider.cs
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzTriggerListener.cs
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobLockProvider.cs
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobLockProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobLockProvider.cs
new file mode 100644
index 000000000..0d5979633
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/IJobLockProvider.cs
@@ -0,0 +1,19 @@
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.BackgroundTasks;
+
+///
+/// 作业锁定提供者
+///
+public interface IJobLockProvider
+{
+ Task TryLockAsync(
+ string jobKey,
+ int lockSeconds,
+ CancellationToken cancellationToken = default);
+
+ Task TryReleaseAsync(
+ string jobKey,
+ CancellationToken cancellationToken = default);
+}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/AbpBackgroundTasksQuartzModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/AbpBackgroundTasksQuartzModule.cs
index 983823e05..788825614 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/AbpBackgroundTasksQuartzModule.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/AbpBackgroundTasksQuartzModule.cs
@@ -15,5 +15,7 @@ public class AbpBackgroundTasksQuartzModule : AbpModule
var _scheduler = context.ServiceProvider.GetRequiredService();
_scheduler.ListenerManager.AddJobListener(context.ServiceProvider.GetRequiredService());
+ _scheduler.ListenerManager.AddTriggerListener(context.ServiceProvider.GetRequiredService());
+
}
}
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 a1070ddb3..c20d3015d 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
@@ -36,10 +36,12 @@ public class QuartzJobExecutorProvider : IQuartzJobExecutorProvider, ISingletonD
}
var adapterType = typeof(QuartzJobSimpleAdapter<>);
- if (job.LockTimeOut > 0)
- {
- adapterType = typeof(QuartzJobConcurrentAdapter<>);
- }
+
+ // 注释, 通过触发器监听锁定
+ //if (job.LockTimeOut > 0)
+ //{
+ // adapterType = typeof(QuartzJobConcurrentAdapter<>);
+ //}
if (!typeof(IJob).IsAssignableFrom(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 b90cb54b6..6ed7e81c8 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,11 +4,12 @@ using Microsoft.Extensions.Logging.Abstractions;
using Quartz;
using Quartz.Listener;
using System;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
-using Volo.Abp.Uow;
+using Volo.Abp.Timing;
namespace LINGYUN.Abp.BackgroundTasks.Quartz;
@@ -18,13 +19,16 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
public override string Name => "QuartzJobListener";
+ protected IClock Clock { get; }
protected IJobEventProvider EventProvider { get; }
protected IServiceProvider ServiceProvider { get; }
public QuartzJobListener(
+ IClock clock,
IServiceProvider serviceProvider,
IJobEventProvider eventProvider)
{
+ Clock = clock;
ServiceProvider = serviceProvider;
EventProvider = eventProvider;
@@ -50,6 +54,12 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
{
try
{
+ var jobEventList = EventProvider.GetAll();
+ if (!jobEventList.Any())
+ {
+ return;
+ }
+
using var scope = ServiceProvider.CreateScope();
var jobEventData = new JobEventData(
jobUUId,
@@ -60,7 +70,6 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
Result = context.Result?.ToString()
};
- var jobEventList = EventProvider.GetAll();
var eventContext = new JobEventContext(
scope.ServiceProvider,
jobEventData);
@@ -86,6 +95,12 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
{
try
{
+ var jobEventList = EventProvider.GetAll();
+ if (!jobEventList.Any())
+ {
+ return;
+ }
+
using var scope = ServiceProvider.CreateScope();
var jobId = context.GetString(nameof(JobInfo.Id));
if (Guid.TryParse(jobId, out var jobUUId))
@@ -112,7 +127,7 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
jobEventData.RepeatCount = simpleTrigger.RepeatCount;
}
jobEventData.Description = context.JobDetail.Description;
- jobEventData.RunTime = context.FireTimeUtc.LocalDateTime;
+ jobEventData.RunTime = Clock.Now;
jobEventData.LastRunTime = context.PreviousFireTimeUtc?.LocalDateTime;
jobEventData.NextRunTime = context.NextFireTimeUtc?.LocalDateTime;
if (context.Result != null)
@@ -125,7 +140,6 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
jobEventData.TenantId = tenantId;
}
- var jobEventList = EventProvider.GetAll();
var eventContext = new JobEventContext(
scope.ServiceProvider,
jobEventData);
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
new file mode 100644
index 000000000..6b4182979
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzTriggerListener.cs
@@ -0,0 +1,56 @@
+using Quartz;
+using Quartz.Listener;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.BackgroundTasks.Quartz;
+
+public class QuartzTriggerListener : TriggerListenerSupport, ISingletonDependency
+{
+ protected const string LockKeyFormat = "p:abp-background-tasks,job:{0},key:{1}";
+
+ public override string Name => "QuartzTriggerListener";
+
+ protected IJobLockProvider JobLockProvider { get; }
+
+ public QuartzTriggerListener(
+ IJobLockProvider jobLockProvider)
+ {
+ JobLockProvider = jobLockProvider;
+ }
+
+ public override async Task VetoJobExecution(
+ ITrigger trigger,
+ IJobExecutionContext context,
+ CancellationToken cancellationToken = default)
+ {
+ context.MergedJobDataMap.TryGetValue(nameof(JobInfo.Id), out var jobId);
+ context.MergedJobDataMap.TryGetValue(nameof(JobInfo.LockTimeOut), out var lockTime);
+ if (jobId != null && lockTime != null && lockTime is int time && time > 0)
+ {
+
+ return !await JobLockProvider.TryLockAsync(NormalizeKey(context, jobId), time, cancellationToken);
+ }
+
+ return false;
+ }
+
+ public override async Task TriggerComplete(
+ ITrigger trigger,
+ IJobExecutionContext context,
+ SchedulerInstruction triggerInstructionCode,
+ CancellationToken cancellationToken = default)
+ {
+ if (context.MergedJobDataMap.TryGetValue(nameof(JobInfo.Id), out var jobId) &&
+ context.MergedJobDataMap.ContainsKey(nameof(JobInfo.LockTimeOut)))
+ {
+ await JobLockProvider.TryReleaseAsync(NormalizeKey(context, jobId), cancellationToken);
+ }
+ }
+
+ protected virtual string NormalizeKey(IJobExecutionContext context, object jobId)
+ {
+ return string.Format(LockKeyFormat, context.JobDetail.JobType.Name, jobId.ToString());
+ }
+}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN.Abp.BackgroundTasks.csproj b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN.Abp.BackgroundTasks.csproj
index 14206d3f2..b49f1e324 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN.Abp.BackgroundTasks.csproj
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN.Abp.BackgroundTasks.csproj
@@ -11,6 +11,7 @@
+
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobLockProvider.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobLockProvider.cs
new file mode 100644
index 000000000..85f286de8
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/JobLockProvider.cs
@@ -0,0 +1,61 @@
+using Microsoft.Extensions.Caching.Memory;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.DistributedLocking;
+
+namespace LINGYUN.Abp.BackgroundTasks;
+
+[Dependency(ReplaceServices = true)]
+public class JobLockProvider : IJobLockProvider, ISingletonDependency
+{
+ protected IMemoryCache LockCache { get; }
+ protected IAbpDistributedLock DistributedLock { get; }
+
+ public JobLockProvider(
+ IMemoryCache lockCache,
+ IAbpDistributedLock distributedLock)
+ {
+ LockCache = lockCache;
+ DistributedLock = distributedLock;
+ }
+
+ public virtual async Task TryLockAsync(string jobKey, int lockSeconds, CancellationToken cancellationToken = default)
+ {
+ var handle = await DistributedLock.TryAcquireAsync(jobKey, cancellationToken: cancellationToken);
+ if (handle != null)
+ {
+ await LockCache.GetOrCreateAsync(jobKey, (entry) =>
+ {
+ entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(lockSeconds));
+ entry.RegisterPostEvictionCallback(async (key, value, reason, state) =>
+ {
+ if (reason == EvictionReason.Expired && value is IAbpDistributedLockHandle handleValue)
+ {
+ await handleValue.DisposeAsync();
+ }
+ });
+ entry.SetValue(handle);
+
+ return Task.FromResult(handle);
+ });
+
+ return true;
+ }
+ return false;
+ }
+
+ public virtual async Task TryReleaseAsync(string jobKey, CancellationToken cancellationToken = default)
+ {
+ if (LockCache.TryGetValue(jobKey, out var handle))
+ {
+ await handle.DisposeAsync();
+
+ LockCache.Remove(jobKey);
+
+ return true;
+ }
+ return false;
+ }
+}
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 042f681fa..9e92ded39 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
@@ -1,17 +1,13 @@
using Microsoft.Extensions.DependencyInjection;
using System;
-using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
-using Volo.Abp.DistributedLocking;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.BackgroundTasks;
public class JobRunnableExecuter : IJobRunnableExecuter, ISingletonDependency
{
- protected const string LockKeyFormat = "p:{0},job:{1},key:{2}";
-
public async virtual Task ExecuteAsync(JobRunnableContext context)
{
Guid? tenantId = null;
@@ -24,31 +20,7 @@ public class JobRunnableExecuter : IJobRunnableExecuter, ISingletonDependency
var currentTenant = context.ServiceProvider.GetRequiredService();
using (currentTenant.Change(tenantId))
{
- context.JobData.TryGetValue(nameof(JobInfo.LockTimeOut), out var lockTime);
-
- // 某些提供者如果无法保证锁一致性, 那么需要用分布式锁
- if (lockTime != null && (lockTime is int time && time > 0))
- {
- var jobId = context.JobData.GetOrDefault(nameof(JobInfo.Id));
- var jobLockKey = string.Format(LockKeyFormat, tenantId?.ToString() ?? "Default", context.JobType.Name, jobId);
- var distributedLock = context.ServiceProvider.GetRequiredService();
-
- var handle = await distributedLock.TryAcquireAsync(jobLockKey, TimeSpan.FromSeconds(time));
- if (handle == null)
- {
- // 抛出异常 通过监听器使其重试
- throw new AbpBackgroundTaskConcurrentException(context.JobType);
- }
-
- await using (handle)
- {
- await InternalExecuteAsync(context);
- }
- }
- else
- {
- await InternalExecuteAsync(context);
- }
+ await InternalExecuteAsync(context);
}
}
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 4ded0bf2a..c9ee39774 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
@@ -156,8 +156,10 @@ public class BackgroundJobInfoAppService : TaskManagementApplicationService, IBa
backgroundJobInfo.MaxCount = input.MaxCount;
backgroundJobInfo.MaxTryCount = input.MaxTryCount;
- backgroundJobInfo.Args.RemoveAll(x => !input.Args.ContainsKey(x.Key));
- backgroundJobInfo.Args.AddIfNotContains(input.Args);
+ foreach (var arg in input.Args)
+ {
+ backgroundJobInfo.Args[arg.Key] = arg.Value;
+ }
backgroundJobInfo.SetPriority(input.Priority);
switch (input.JobType)
diff --git a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj
index e64223cd1..3ce7471c7 100644
--- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj
+++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/LY.MicroService.TaskManagement.HttpApi.Host.csproj
@@ -38,6 +38,7 @@
+
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 2ea812a44..44bd38542 100644
--- a/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs
+++ b/aspnet-core/services/LY.MicroService.TaskManagement.HttpApi.Host/TaskManagementHttpApiHostModule.cs
@@ -22,6 +22,7 @@ using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.Caching.StackExchangeRedis;
+using Volo.Abp.DistributedLocking;
using Volo.Abp.EntityFrameworkCore.MySQL;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Http.Client.IdentityModel.Web;
@@ -38,6 +39,7 @@ namespace LY.MicroService.TaskManagement;
typeof(AbpSerilogEnrichersUniqueIdModule),
typeof(AbpAuditLoggingElasticsearchModule),
typeof(AbpAspNetCoreSerilogModule),
+ typeof(AbpDistributedLockingModule),
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
typeof(AbpEmailingExceptionHandlingModule),
From 6017f03a5ebf4ad2fe42043c67e6f96344c45ca3 Mon Sep 17 00:00:00 2001
From: cKey <35512826+colinin@users.noreply.github.com>
Date: Wed, 12 Jan 2022 11:54:29 +0800
Subject: [PATCH 2/2] =?UTF-8?q?feat(tasks):=20=E5=AE=8C=E5=96=84=E4=BD=9C?=
=?UTF-8?q?=E4=B8=9A=E5=BC=82=E5=B8=B8=E6=8E=A8=E9=80=81.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../JobRunnableContextExtensions.cs | 2 +-
...p.BackgroundTasks.ExceptionHandling.csproj | 10 ++
...pBackgroundTasksExceptionHandlingModule.cs | 16 +++
.../ExceptionHandling/JobExceptionNotifier.cs | 109 +++++++++++-------
.../Localization/Resources/en.json | 15 +++
.../Localization/Resources/zh-Hans.json | 15 +++
.../Abp/BackgroundTasks/Jobs/ConsoleJob.cs | 2 +-
.../Abp/BackgroundTasks/Jobs/SendEmailJob.cs | 30 ++++-
.../Quartz/QuartzJobScheduler.cs | 7 +-
.../AbpBackgroundTasksModule.cs | 16 +++
.../Internal/JobExecutedEvent.cs | 2 +-
.../Localization/BackgroundTasksResource.cs | 8 ++
.../Localization/Resources/en.json | 5 +
.../Localization/Resources/zh-Hans.json | 5 +
.../TaskManagement/BackgroundJobManager.cs | 9 +-
15 files changed, 198 insertions(+), 53 deletions(-)
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/en.json
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/zh-Hans.json
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/BackgroundTasksResource.cs
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/en.json
create mode 100644 aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/zh-Hans.json
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs
index c87d46bc5..bb0139e9d 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobRunnableContextExtensions.cs
@@ -71,7 +71,7 @@ public static class JobRunnableContextExtensions
{
return value;
}
- throw new ArgumentException($"Job required data {key} not specified.");
+ throw new ArgumentException($"Job required data [{key}] not specified.");
}
public static bool TryGetJobData(this JobRunnableContext context, string key, out object value)
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj
index 74c4f48de..a5dd97fab 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj
@@ -8,6 +8,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs
index 0f11234c3..705a36a01 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs
@@ -1,5 +1,8 @@
using LINGYUN.Abp.BackgroundTasks.Jobs;
+using LINGYUN.Abp.BackgroundTasks.Localization;
+using Volo.Abp.Localization;
using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
@@ -7,5 +10,18 @@ namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
[DependsOn(typeof(AbpBackgroundTasksJobsModule))]
public class AbpBackgroundTasksExceptionHandlingModule : AbpModule
{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+ Configure(options =>
+ {
+ options.Resources
+ .Get()
+ .AddVirtualJson("/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources");
+ });
+ }
}
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/JobExceptionNotifier.cs
index 1dda90249..e8f4927fc 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/JobExceptionNotifier.cs
@@ -1,10 +1,16 @@
using JetBrains.Annotations;
using LINGYUN.Abp.BackgroundTasks.Jobs;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.Emailing;
+using Volo.Abp.MultiTenancy;
+using Volo.Abp.TextTemplating;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
@@ -13,64 +19,89 @@ namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
public class JobExceptionNotifier : IJobExceptionNotifier, ITransientDependency
{
public const string Prefix = "exception.";
+ public const string JobGroup = "ExceptionNotifier";
+
+ public ILogger Logger { protected get; set; }
protected IClock Clock { get; }
- protected IJobStore JobStore { get; }
- protected IJobScheduler JobScheduler { get; }
+ protected IEmailSender EmailSender { get; }
+ protected ITemplateRenderer TemplateRenderer { get; }
public JobExceptionNotifier(
IClock clock,
- IJobStore jobStore,
- IJobScheduler jobScheduler)
+ IEmailSender emailSender,
+ ITemplateRenderer templateRenderer)
{
Clock = clock;
- JobStore = jobStore;
- JobScheduler = jobScheduler;
+ EmailSender = emailSender;
+ TemplateRenderer = templateRenderer;
+
+ Logger = NullLogger.Instance;
}
public virtual async Task NotifyAsync([NotNull] JobExceptionNotificationContext context)
{
+ // 异常所属分组不处理, 防止死循环
+ if (string.Equals(context.JobInfo.Group, JobGroup))
+ {
+ Logger.LogWarning($"There is a problem executing the job, reason: {context.Exception.Message}");
+ return;
+ }
var notifyKey = Prefix + SendEmailJob.PropertyTo;
- if (context.JobInfo.Args.TryGetValue(notifyKey, out var exceptionTo))
+ if (context.JobInfo.Args.TryGetValue(notifyKey, out var exceptionTo) &&
+ exceptionTo is string to)
{
- var template = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyTemplate) ?? "";
- var subject = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertySubject) ?? "From job execute exception";
- var globalContext = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyContext) ?? "{}";
- var from = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyFrom) ?? "";
- var culture = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyCulture) ?? CultureInfo.CurrentCulture.Name;
+ 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 jobId = Guid.NewGuid();
- var jobArgs = new Dictionary
+ if (template.IsNullOrWhiteSpace())
{
- { SendEmailJob.PropertyTo, exceptionTo.ToString() },
- { SendEmailJob.PropertySubject, subject },
- { SendEmailJob.PropertyBody, context.Exception.GetBaseException().Message },
- { SendEmailJob.PropertyTemplate, template },
- { SendEmailJob.PropertyContext, globalContext },
- { SendEmailJob.PropertyFrom, from },
- { SendEmailJob.PropertyCulture, culture }
- };
- var jobInfo = new JobInfo
+ await EmailSender.SendAsync(from, to, subject, content, false);
+ return;
+ }
+
+ var footer = context.JobInfo.Args.GetOrDefault("footer")?.ToString() ?? $"Copyright to LY Colin © {Clock.Now.Year}";
+ var model = new
{
- Id = jobId,
- Name = jobId.ToString(),
- Group = "ExceptionHandling",
- Priority = JobPriority.Normal,
- BeginTime = Clock.Now,
- Args = jobArgs,
- Description = subject.ToString(),
- JobType = JobType.Once,
- Interval = 5,
- MaxCount = 1,
- MaxTryCount = 1,
- CreationTime = Clock.Now,
- Status = JobStatus.None,
- Type = DefaultJobNames.SendEmailJob,
+ Title = subject,
+ Group = context.JobInfo.Group,
+ Name = context.JobInfo.Name,
+ Id = context.JobInfo.Id,
+ Type = context.JobInfo.Type,
+ Triggertime = Clock.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ Message = errorMessage,
+ Tenantname = context.JobInfo.Args.GetOrDefault(nameof(IMultiTenant.TenantId)),
+ Footer = footer,
};
- await JobStore.StoreAsync(jobInfo);
+ var globalContext = new Dictionary();
+ if (context.JobInfo.Args.TryGetValue(Prefix + SendEmailJob.PropertyContext, out var ctx) &&
+ ctx is string ctxStr && !ctxStr.IsNullOrWhiteSpace())
+ {
+ try
+ {
+ globalContext = JsonConvert.DeserializeObject>(ctxStr);
+ }
+ catch { }
+ }
+
+ var culture = context.JobInfo.Args.GetOrDefault(Prefix + SendEmailJob.PropertyCulture)?.ToString() ?? CultureInfo.CurrentCulture.Name;
- await JobScheduler.TriggerAsync(jobInfo);
+ content = await TemplateRenderer.RenderAsync(
+ templateName: template,
+ model: model,
+ cultureName: culture,
+ globalContext: globalContext);
+
+ if (from.IsNullOrWhiteSpace())
+ {
+ await EmailSender.SendAsync(to, subject, content, true);
+ return;
+ }
+ await EmailSender.SendAsync(from, to, subject, content, true);
}
}
}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/en.json b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/en.json
new file mode 100644
index 000000000..15dff07ad
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/en.json
@@ -0,0 +1,15 @@
+{
+ "culture": "en",
+ "texts": {
+ "TextTemplate:JobExceptionNotifier": "Background job exception pushes template",
+ "JobExceptionNotifier": "Background job exception push",
+ "TenantName": "TenantName",
+ "JobGroup": "Job Group",
+ "JobName": "Job Name",
+ "JobId": "Job Id",
+ "JobType": "Job Type",
+ "TriggerTime": "Trigger Time",
+ "ErrorMessage": "Error Message",
+ "JobExecuteError": "Background job exception"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/zh-Hans.json b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/zh-Hans.json
new file mode 100644
index 000000000..4975448b6
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/Localization/Resources/zh-Hans.json
@@ -0,0 +1,15 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ "TextTemplate:JobExceptionNotifier": "后台作业异常推送模板",
+ "JobExceptionNotifier": "后台作业异常推送",
+ "TenantName": "租户名称",
+ "JobGroup": "作业分组",
+ "JobName": "作业名称",
+ "JobId": "作业标识",
+ "JobType": "作业类型",
+ "TriggerTime": "触发时间",
+ "ErrorMessage": "错误消息",
+ "JobExecuteError": "后台作业异常"
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ConsoleJob.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ConsoleJob.cs
index 88320073d..abc1d747f 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ConsoleJob.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/ConsoleJob.cs
@@ -9,7 +9,7 @@ public class ConsoleJob : IJobRunnable
public Task ExecuteAsync(JobRunnableContext context)
{
context.TryGetString(PropertyMessage, out var message);
- Console.WriteLine($"This message: {message ?? "None"} comes from the job: {GetType()}");
+ Console.WriteLine($"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}] - This message: {message ?? "None"} comes from the job: {GetType()}");
return Task.CompletedTask;
}
}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs
index 0864919bc..022429be5 100644
--- a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Jobs/LINGYUN/Abp/BackgroundTasks/Jobs/SendEmailJob.cs
@@ -4,6 +4,7 @@ using Volo.Abp.TextTemplating;
using Volo.Abp.Json;
using System.Collections.Generic;
using System;
+using Newtonsoft.Json;
namespace LINGYUN.Abp.BackgroundTasks.Jobs;
@@ -28,6 +29,10 @@ public class SendEmailJob : IJobRunnable
///
public const string PropertyTemplate = "template";
///
+ /// 可选, 模板消息中的模型参数
+ ///
+ public const string PropertyModel = "model";
+ ///
/// 可选, 模板消息中的上下文参数
///
public const string PropertyContext = "context";
@@ -58,19 +63,40 @@ public class SendEmailJob : IJobRunnable
catch { }
}
+ object model = null;
+ if (context.TryGetString(PropertyModel, out var modelString) && !modelString.IsNullOrWhiteSpace())
+ {
+ try
+ {
+ model = JsonConvert.DeserializeObject(modelString);
+ }
+ catch { }
+ }
+
var templateRenderer = context.GetRequiredService();
var content = await templateRenderer.RenderAsync(
templateName: template,
+ model: model,
cultureName: culture,
globalContext: globalContext);
- await emailSender.QueueAsync(from, to, subject, content, true);
+ await QueueEmail(emailSender, from, to, subject, content, true);
return;
}
var body = context.GetString(PropertyBody);
- await emailSender.QueueAsync(from, to, subject, body, false);
+ await QueueEmail(emailSender, from, to, subject, body, false);
+ }
+
+ private async Task QueueEmail(IEmailSender emailSender, string from, string to, string subject, string body, bool isBodyHtml = true)
+ {
+ if (from.IsNullOrWhiteSpace())
+ {
+ await emailSender.SendAsync(to, subject, body, isBodyHtml);
+ return;
+ }
+ await emailSender.SendAsync(from, to, subject, body, isBodyHtml);
}
}
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 af3be1c45..d6d5dc5d0 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
@@ -154,10 +154,11 @@ public class QuartzJobScheduler : IJobScheduler, ISingletonDependency
var jobKey = new JobKey(job.Name, job.Group);
if (!await Scheduler.CheckExists(jobKey))
{
- job.JobType = JobType.Once;
-
await QueueAsync(job);
}
- await Scheduler.TriggerJob(jobKey);
+ else
+ {
+ await Scheduler.TriggerJob(jobKey);
+ }
}
}
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 94c50a110..644cf3c30 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,14 +1,18 @@
using LINGYUN.Abp.BackgroundTasks.Internal;
+using LINGYUN.Abp.BackgroundTasks.Localization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Auditing;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Guids;
+using Volo.Abp.Localization;
using Volo.Abp.Modularity;
+using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.BackgroundTasks;
[DependsOn(typeof(AbpAuditingModule))]
+[DependsOn(typeof(AbpLocalizationModule))]
[DependsOn(typeof(AbpBackgroundTasksAbstractionsModule))]
[DependsOn(typeof(AbpBackgroundJobsAbstractionsModule))]
[DependsOn(typeof(AbpDistributedLockingAbstractionsModule))]
@@ -19,5 +23,17 @@ public class AbpBackgroundTasksModule : AbpModule
{
context.Services.AddTransient(typeof(BackgroundJobAdapter<>));
context.Services.AddHostedService();
+
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+
+ Configure(options =>
+ {
+ options.Resources
+ .Add("en")
+ .AddVirtualJson("/LINGYUN/Abp/BackgroundTasks/Localization/Resources");
+ });
}
}
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 922eb911c..8fd996c10 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
@@ -47,7 +47,7 @@ public class JobExecutedEvent : JobEventBase, ITransientDepend
job.Priority = JobPriority.Low;
}
- if (job.TryCount > job.MaxTryCount)
+ if (job.TryCount >= job.MaxTryCount)
{
job.Status = JobStatus.Stopped;
job.IsAbandoned = true;
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/BackgroundTasksResource.cs b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/BackgroundTasksResource.cs
new file mode 100644
index 000000000..f75030a1e
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/BackgroundTasksResource.cs
@@ -0,0 +1,8 @@
+using Volo.Abp.Localization;
+
+namespace LINGYUN.Abp.BackgroundTasks.Localization;
+
+[LocalizationResourceName("BackgroundTasks")]
+public class BackgroundTasksResource
+{
+}
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/en.json b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/en.json
new file mode 100644
index 000000000..a9c8dcc3f
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/en.json
@@ -0,0 +1,5 @@
+{
+ "culture": "en",
+ "texts": {
+ }
+}
\ No newline at end of file
diff --git a/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/zh-Hans.json b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/zh-Hans.json
new file mode 100644
index 000000000..c5ad81326
--- /dev/null
+++ b/aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Localization/Resources/zh-Hans.json
@@ -0,0 +1,5 @@
+{
+ "culture": "zh-Hans",
+ "texts": {
+ }
+}
\ No newline at end of file
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 fbf5b541f..fcede54a9 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
@@ -92,12 +92,9 @@ public class BackgroundJobManager : DomainService
public virtual async Task TriggerAsync(BackgroundJobInfo jobInfo)
{
var job = ObjectMapper.Map(jobInfo);
- //if (!await JobScheduler.ExistsAsync(job))
- //{
- // throw new BusinessException(TaskManagementErrorCodes.JobNotFoundInQueue)
- // .WithData("Group", job.Group)
- // .WithData("Name", job.Name);
- //}
+ job.JobType = JobType.Once;
+ // 延迟两秒触发
+ job.Interval = 2;
await JobScheduler.TriggerAsync(job);
}