Browse Source

Merge pull request #1257 from colinin/enhance-background-tasks

feat(tasks): enhance background tasks
pull/1267/head
yx lin 9 months ago
committed by GitHub
parent
commit
e88dca8a5e
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 5
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/DefaultJobExceptionTypeFinder.cs
  2. 36
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventBase.cs
  3. 8
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventData.cs
  4. 21
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Activities/LINGYUN/Abp/BackgroundTasks/Activities/IJobActionFilter.cs
  5. 11
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Activities/LINGYUN/Abp/BackgroundTasks/Activities/JobActionEvent.cs
  6. 1
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs
  7. 17
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Notifications/LINGYUN/Abp/BackgroundTasks/Notifications/Templates/BackgroundTasksNotificationTemplateDefinitionProvider.cs
  8. 8
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobListener.cs
  9. 4
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobSearchJobAdapter.cs
  10. 4
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobSimpleAdapter.cs
  11. 9
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs
  12. 11
      aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobLogEvent.cs

5
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/DefaultJobExceptionTypeFinder.cs

@ -48,6 +48,11 @@ public class DefaultJobExceptionTypeFinder : IJobExceptionTypeFinder, ITransient
return JobExceptionType.Network;
}
if (httpStatusCode.HttpStatusCode >= 500)
{
return JobExceptionType.System;
}
return JobExceptionType.Application;
}

36
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventBase.cs

@ -19,12 +19,15 @@ public abstract class JobEventBase<TEvent> : IJobEvent
{
try
{
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
using (currentTenant.Change(context.EventData.TenantId))
if (await CanAfterExecuted(context))
{
Logger.LogInformation("Job {Group}-{Name} after event with {Event} has executing.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
await OnJobAfterExecutedAsync(context);
Logger.LogInformation("Job {Group}-{Name} after event with {Event} was executed.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
using (currentTenant.Change(context.EventData.TenantId))
{
Logger.LogInformation("Job {Group}-{Name} after event with {Event} has executing.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
await OnJobAfterExecutedAsync(context);
Logger.LogInformation("Job {Group}-{Name} after event with {Event} was executed.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
}
}
}
catch (Exception ex)
@ -37,12 +40,15 @@ public abstract class JobEventBase<TEvent> : IJobEvent
{
try
{
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
using (currentTenant.Change(context.EventData.TenantId))
if (await CanBeforeExecuted(context))
{
Logger.LogInformation("Job {Group}-{Name} before event with {Event} executing.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
await OnJobBeforeExecutedAsync(context);
Logger.LogInformation("Job {Group}-{Name} before event with {Event} was executed.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
var currentTenant = context.ServiceProvider.GetRequiredService<ICurrentTenant>();
using (currentTenant.Change(context.EventData.TenantId))
{
Logger.LogInformation("Job {Group}-{Name} before event with {Event} executing.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
await OnJobBeforeExecutedAsync(context);
Logger.LogInformation("Job {Group}-{Name} before event with {Event} was executed.", context.EventData.Group, context.EventData.Name, typeof(TEvent).Name);
}
}
}
catch (Exception ex)
@ -51,11 +57,21 @@ public abstract class JobEventBase<TEvent> : IJobEvent
}
}
protected virtual Task<bool> CanAfterExecuted(JobEventContext context)
{
return Task.FromResult(true);
}
protected virtual Task OnJobAfterExecutedAsync(JobEventContext context)
{
return Task.CompletedTask;
}
protected virtual Task<bool> CanBeforeExecuted(JobEventContext context)
{
return Task.FromResult(true);
}
protected virtual Task OnJobBeforeExecutedAsync(JobEventContext context)
{
return Task.CompletedTask;

8
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Abstractions/LINGYUN/Abp/BackgroundTasks/JobEventData.cs

@ -59,6 +59,10 @@ public class JobEventData
/// </summary>
public DateTime RunTime { get; set; }
/// <summary>
/// 执行时间(ms)
/// </summary>
public int? ExecutionDuration { get; set; }
/// <summary>
/// 上次运行时间
/// </summary>
public DateTime? LastRunTime { get; set; }
@ -66,7 +70,9 @@ public class JobEventData
/// 下次运行时间
/// </summary>
public DateTime? NextRunTime { get; set; }
/// <summary>
/// 作业取消令牌
/// </summary>
public CancellationToken CancellationToken { get; }
public JobEventData(
string key,

21
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Activities/LINGYUN/Abp/BackgroundTasks/Activities/IJobActionFilter.cs

@ -0,0 +1,21 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.BackgroundTasks.Activities;
/// <summary>
/// 作业行为过滤器
/// </summary>
public interface IJobActionFilter
{
/// <summary>
/// 是否允许触发后操作
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
Task<bool> CanAfterExecuted(JobEventContext context);
/// <summary>
/// 是否允许触发前操作
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
Task<bool> CanBeforeExecuted(JobEventContext context);
}

11
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Activities/LINGYUN/Abp/BackgroundTasks/Activities/JobActionEvent.cs

@ -10,6 +10,17 @@ namespace LINGYUN.Abp.BackgroundTasks.Activities;
public class JobActionEvent : JobEventBase<JobActionEvent>, ITransientDependency
{
protected override Task<bool> CanAfterExecuted(JobEventContext context)
{
var filter = context.ServiceProvider.GetService<IJobActionFilter>();
if (filter != null)
{
return filter.CanAfterExecuted(context);
}
return base.CanAfterExecuted(context);
}
protected async override Task OnJobAfterExecutedAsync(JobEventContext context)
{
if (context.EventData.Type.IsDefined(typeof(DisableJobActionAttribute), true))

1
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/AbpBackgroundTasksExceptionHandlingModule.cs

@ -7,6 +7,7 @@ using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.BackgroundTasks.ExceptionHandling;
[System.Obsolete("Please use the `AbpBackgroundTasksNotificationsModule` module")]
[DependsOn(typeof(AbpBackgroundTasksActivitiesModule))]
[DependsOn(typeof(AbpEmailingModule))]
public class AbpBackgroundTasksExceptionHandlingModule : AbpModule

17
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Notifications/LINGYUN/Abp/BackgroundTasks/Notifications/Templates/BackgroundTasksNotificationTemplateDefinitionProvider.cs

@ -1,7 +1,4 @@
using LINGYUN.Abp.BackgroundTasks.Localization;
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Localization;
using Volo.Abp.TextTemplating;
@ -17,13 +14,13 @@ public class BackgroundTasksNotificationTemplateDefinitionProvider : TemplateDef
{
return new[]
{
new TemplateDefinition(
BackgroundTasksNotificationTemplates.JobExecutedNotification,
displayName: L("TextTemplate:JobExecutedNotification"),
localizationResource: typeof(BackgroundTasksResource)
).WithVirtualFilePath(
"/LINGYUN/Abp/BackgroundTasks/Notifications/Templates/JobExecutedNotification.tpl",
isInlineLocalized: true)
new TemplateDefinition(
BackgroundTasksNotificationTemplates.JobExecutedNotification,
displayName: L("TextTemplate:JobExecutedNotification"),
localizationResource: typeof(BackgroundTasksResource)
).WithVirtualFilePath(
"/LINGYUN/Abp/BackgroundTasks/Notifications/Templates/JobExecutedNotification.tpl",
isInlineLocalized: true)
};
}

8
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobListener.cs

@ -129,6 +129,14 @@ public class QuartzJobListener : JobListenerSupport, ISingletonDependency
}
jobEventData.Description = context.JobDetail.Description;
jobEventData.RunTime = Clock.Normalize(context.FireTimeUtc.LocalDateTime);
var runTimeCache = context.Get(nameof(JobEventData.RunTime));
if (runTimeCache != null && runTimeCache is DateTime runTime)
{
jobEventData.RunTime = runTime;
jobEventData.ExecutionDuration = (Clock.Now - runTime).Milliseconds;
}
var lastRunTime = context.PreviousFireTimeUtc?.LocalDateTime ?? context.Trigger.GetPreviousFireTimeUtc()?.LocalDateTime;
if (lastRunTime.HasValue)
{

4
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobSearchJobAdapter.cs

@ -2,6 +2,7 @@
using Quartz;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.BackgroundTasks.Quartz;
@ -24,8 +25,11 @@ public class QuartzJobSearchJobAdapter : IJob
var jobDefinition = JobDefinitionManager.Get(jobType);
using var scope = ServiceScopeFactory.CreateScope();
var clock = scope.ServiceProvider.GetRequiredService<IClock>();
var jobExecuter = scope.ServiceProvider.GetRequiredService<IJobRunnableExecuter>();
context.Put(nameof(JobEventData.RunTime), clock.Now);
var jobContext = new JobRunnableContext(
jobDefinition.JobType,
scope.ServiceProvider,

4
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.Quartz/LINGYUN/Abp/BackgroundTasks/Quartz/QuartzJobSimpleAdapter.cs

@ -2,6 +2,7 @@
using Quartz;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.BackgroundTasks.Quartz;
@ -19,8 +20,11 @@ public class QuartzJobSimpleAdapter<TJobRunnable> : IJob
public async virtual Task Execute(IJobExecutionContext context)
{
using var scope = ServiceScopeFactory.CreateScope();
var clock = scope.ServiceProvider.GetRequiredService<IClock>();
var jobExecuter = scope.ServiceProvider.GetRequiredService<IJobRunnableExecuter>();
context.Put(nameof(JobEventData.RunTime), clock.Now);
var jobContext = new JobRunnableContext(
typeof(TJobRunnable),
scope.ServiceProvider,

9
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobExecutedEvent.cs

@ -9,13 +9,18 @@ namespace LINGYUN.Abp.BackgroundTasks.Internal;
public class JobExecutedEvent : JobEventBase<JobExecutedEvent>, ITransientDependency
{
protected override async Task OnJobAfterExecutedAsync(JobEventContext context)
protected override Task<bool> CanAfterExecuted(JobEventContext context)
{
if (context.EventData.Type.IsDefined(typeof(DisableJobStatusAttribute), true))
{
Logger.LogWarning("The job change event could not be processed because the job marked the DisableJobStatus attribute!");
return;
return Task.FromResult(false);
}
return base.CanAfterExecuted(context);
}
protected override async Task OnJobAfterExecutedAsync(JobEventContext context)
{
var store = context.ServiceProvider.GetRequiredService<IJobStore>();
var job = await store.FindAsync(context.EventData.Key, context.EventData.CancellationToken);
if (job == null)

11
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks/LINGYUN/Abp/BackgroundTasks/Internal/JobLogEvent.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
@ -13,12 +14,18 @@ namespace LINGYUN.Abp.BackgroundTasks.Internal;
/// </remarks>
public class JobLogEvent : JobEventBase<JobLogEvent>, ITransientDependency
{
protected async override Task OnJobAfterExecutedAsync(JobEventContext context)
protected override Task<bool> CanAfterExecuted(JobEventContext context)
{
if (context.EventData.Type.IsDefined(typeof(DisableAuditingAttribute), true))
{
return;
Logger.LogWarning("The job change event could not be processed because the job marked the DisableAuditing attribute!");
return Task.FromResult(false);
}
return base.CanAfterExecuted(context);
}
protected async override Task OnJobAfterExecutedAsync(JobEventContext context)
{
var store = context.ServiceProvider.GetRequiredService<IJobStore>();
await store.StoreLogAsync(context.EventData);
}

Loading…
Cancel
Save