52 changed files with 601 additions and 287 deletions
@ -1,33 +1,7 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Volo.Abp.Modularity; |
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using Volo.Abp.Modularity; |
|
||||
using Volo.Abp.Reflection; |
|
||||
|
|
||||
namespace LINGYUN.Abp.BackgroundTasks; |
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
public class AbpBackgroundTasksAbstractionsModule : AbpModule |
public class AbpBackgroundTasksAbstractionsModule : AbpModule |
||||
{ |
{ |
||||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
AutoAddJobMonitors(context.Services); |
|
||||
} |
|
||||
|
|
||||
private static void AutoAddJobMonitors(IServiceCollection services) |
|
||||
{ |
|
||||
var jobMonitors = new List<Type>(); |
|
||||
|
|
||||
services.OnRegistred(context => |
|
||||
{ |
|
||||
if (ReflectionHelper.IsAssignableToGenericType(context.ImplementationType, typeof(JobEventBase<>))) |
|
||||
{ |
|
||||
jobMonitors.Add(context.ImplementationType); |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
services.Configure<AbpBackgroundTasksOptions>(options => |
|
||||
{ |
|
||||
options.JobMonitors.AddIfNotContains(jobMonitors); |
|
||||
}); |
|
||||
} |
|
||||
} |
} |
||||
|
|||||
@ -0,0 +1,9 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
public interface IJobCompletedNotifierProvider |
||||
|
{ |
||||
|
Task NotifyComplateAsync([NotNull] JobEventContext context); |
||||
|
} |
||||
@ -1,9 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace LINGYUN.Abp.BackgroundTasks; |
|
||||
|
|
||||
public interface IJobExceptionNotifier |
|
||||
{ |
|
||||
Task NotifyAsync([NotNull] JobExceptionNotificationContext context); |
|
||||
} |
|
||||
@ -0,0 +1,11 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
public interface IJobExecutedNotifier |
||||
|
{ |
||||
|
Task NotifyErrorAsync([NotNull] JobEventContext context); |
||||
|
Task NotifySuccessAsync([NotNull] JobEventContext context); |
||||
|
Task NotifyComplateAsync([NotNull] JobEventContext context); |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
public interface IJobFailedNotifierProvider |
||||
|
{ |
||||
|
Task NotifyErrorAsync([NotNull] JobEventContext context); |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
public interface IJobSuccessNotifierProvider |
||||
|
{ |
||||
|
Task NotifySuccessAsync([NotNull] JobEventContext context); |
||||
|
} |
||||
@ -1,16 +0,0 @@ |
|||||
using System; |
|
||||
|
|
||||
namespace LINGYUN.Abp.BackgroundTasks; |
|
||||
|
|
||||
public class JobExceptionNotificationContext |
|
||||
{ |
|
||||
public JobInfo JobInfo { get; } |
|
||||
public Exception Exception { get; } |
|
||||
public JobExceptionNotificationContext( |
|
||||
JobInfo jobInfo, |
|
||||
Exception exception) |
|
||||
{ |
|
||||
JobInfo = jobInfo; |
|
||||
Exception = exception; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,67 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using Microsoft.Extensions.Logging.Abstractions; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
public class JobExecutedNotifier : IJobExecutedNotifier, ISingletonDependency |
||||
|
{ |
||||
|
public ILogger<JobExecutedNotifier> Logger { protected get; set; } |
||||
|
|
||||
|
public JobExecutedNotifier() |
||||
|
{ |
||||
|
Logger = NullLogger<JobExecutedNotifier>.Instance; |
||||
|
} |
||||
|
|
||||
|
public async Task NotifyComplateAsync([NotNull] JobEventContext context) |
||||
|
{ |
||||
|
var notifier = context.ServiceProvider.GetService<IJobCompletedNotifierProvider>(); |
||||
|
if (notifier != null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
await notifier.NotifyComplateAsync(context); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning($"An exception thow with job complete notify: {ex.Message}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task NotifyErrorAsync([NotNull] JobEventContext context) |
||||
|
{ |
||||
|
var notifier = context.ServiceProvider.GetService<IJobFailedNotifierProvider>(); |
||||
|
if (notifier != null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
await notifier.NotifyErrorAsync(context); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning($"An exception thow with job error notify: {ex.Message}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public async Task NotifySuccessAsync([NotNull] JobEventContext context) |
||||
|
{ |
||||
|
var notifier = context.ServiceProvider.GetService<IJobSuccessNotifierProvider>(); |
||||
|
if (notifier != null) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
await notifier.NotifySuccessAsync(context); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning($"An exception thow with job success notify: {ex.Message}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,14 +0,0 @@ |
|||||
using JetBrains.Annotations; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
|
||||
|
|
||||
namespace LINGYUN.Abp.BackgroundTasks; |
|
||||
|
|
||||
[Dependency(TryRegister = true)] |
|
||||
public class NullJobExceptionNotifier : IJobExceptionNotifier, ISingletonDependency |
|
||||
{ |
|
||||
public Task NotifyAsync([NotNull] JobExceptionNotificationContext context) |
|
||||
{ |
|
||||
return Task.CompletedTask; |
|
||||
} |
|
||||
} |
|
||||
45
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobFailedNotifierProvider.cs
45
aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobExceptionNotifier.cs → aspnet-core/modules/task-management/LINGYUN.Abp.BackgroundTasks.ExceptionHandling/LINGYUN/Abp/BackgroundTasks/ExceptionHandling/JobFailedNotifierProvider.cs
@ -0,0 +1,6 @@ |
|||||
|
namespace LINGYUN.Abp.BackgroundTasks.Jobs; |
||||
|
|
||||
|
internal static class BackgroundTasksConsts |
||||
|
{ |
||||
|
public const string DefaultHttpClient = "_AbpBackgroundTasks_Client"; |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\LINGYUN.Abp.BackgroundTasks\LINGYUN.Abp.BackgroundTasks.csproj" /> |
||||
|
<ProjectReference Include="..\LINGYUN.Abp.TaskManagement.HttpApi.Client\LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,11 @@ |
|||||
|
using LINGYUN.Abp.TaskManagement.HttpApi.Client; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks.TaskManagement; |
||||
|
|
||||
|
[DependsOn(typeof(AbpBackgroundTasksModule))] |
||||
|
[DependsOn(typeof(TaskManagementHttpApiClientModule))] |
||||
|
public class AbpBackgroundTasksTaskManagementModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
using LINGYUN.Abp.TaskManagement; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks.TaskManagement; |
||||
|
|
||||
|
public class TaskManagementJobPublisher : IJobPublisher, ITransientDependency |
||||
|
{ |
||||
|
protected IBackgroundJobInfoAppService BackgroundJobAppService { get; } |
||||
|
|
||||
|
public TaskManagementJobPublisher( |
||||
|
IBackgroundJobInfoAppService backgroundJobAppService) |
||||
|
{ |
||||
|
BackgroundJobAppService = backgroundJobAppService; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<bool> PublishAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var input = new BackgroundJobInfoCreateDto |
||||
|
{ |
||||
|
Cron = job.Cron, |
||||
|
MaxCount = job.MaxCount, |
||||
|
MaxTryCount = job.MaxTryCount, |
||||
|
Args = new ExtraPropertyDictionary(job.Args), |
||||
|
BeginTime = job.BeginTime, |
||||
|
Description = job.Description, |
||||
|
EndTime = job.EndTime, |
||||
|
Group = job.Group, |
||||
|
Interval = job.Interval, |
||||
|
Type = job.Type, |
||||
|
JobType = job.JobType, |
||||
|
LockTimeOut = job.LockTimeOut, |
||||
|
IsEnabled = true, |
||||
|
Name = job.Name, |
||||
|
Priority = job.Priority, |
||||
|
}; |
||||
|
|
||||
|
await BackgroundJobAppService.CreateAsync(input); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
public interface IJobPublisher |
||||
|
{ |
||||
|
Task<bool> PublishAsync(JobInfo job, CancellationToken cancellationToken = default); |
||||
|
} |
||||
@ -1,27 +0,0 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.Auditing; |
|
||||
|
|
||||
namespace LINGYUN.Abp.BackgroundTasks.Internal; |
|
||||
|
|
||||
[DisableAuditing] |
|
||||
public class BackgroundKeepAliveJob : IJobRunnable |
|
||||
{ |
|
||||
public virtual async Task ExecuteAsync(JobRunnableContext context) |
|
||||
{ |
|
||||
var store = context.ServiceProvider.GetRequiredService<IJobStore>(); |
|
||||
|
|
||||
// TODO: 如果积压有大量周期性任务, 可能后面的队列无法被检索到
|
|
||||
var periodJobs = await store.GetAllPeriodTasksAsync(); |
|
||||
|
|
||||
if (!periodJobs.Any()) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
var jobScheduler = context.ServiceProvider.GetRequiredService<IJobScheduler>(); |
|
||||
|
|
||||
await jobScheduler.QueuesAsync(periodJobs); |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,32 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks.Internal; |
||||
|
|
||||
|
public class JobNotifierEvent : JobEventBase<JobNotifierEvent>, ITransientDependency |
||||
|
{ |
||||
|
protected async override Task OnJobAfterExecutedAsync(JobEventContext context) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
var notifier = context.ServiceProvider.GetRequiredService<IJobExecutedNotifier>(); |
||||
|
if (context.EventData.Exception != null) |
||||
|
{ |
||||
|
await notifier.NotifyErrorAsync(context); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
await notifier.NotifySuccessAsync(context); |
||||
|
} |
||||
|
|
||||
|
await notifier.NotifyComplateAsync(context); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
Logger.LogWarning($"An exception thow with job notify: {ex.Message}"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
[Dependency(TryRegister = true)] |
||||
|
public class NullJobPublisher : IJobPublisher, ISingletonDependency |
||||
|
{ |
||||
|
public Task<bool> PublishAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LINGYUN.Abp.BackgroundTasks; |
||||
|
|
||||
|
[Dependency(TryRegister = true)] |
||||
|
public class NullJobScheduler : IJobScheduler, ISingletonDependency |
||||
|
{ |
||||
|
public Task<bool> ExistsAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
|
||||
|
public Task PauseAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public Task<bool> QueueAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
|
||||
|
public Task QueuesAsync(IEnumerable<JobInfo> jobs, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public Task<bool> RemoveAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
|
||||
|
public Task ResumeAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
|
||||
|
public Task<bool> ShutdownAsync(CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
|
||||
|
public Task<bool> StartAsync(CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
|
||||
|
public Task<bool> StopAsync(CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
|
||||
|
public Task TriggerAsync(JobInfo job, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Volo.Abp.Http.Client" Version="$(VoloAbpPackageVersion)" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\LINGYUN.Abp.TaskManagement.Application.Contracts\LINGYUN.Abp.TaskManagement.Application.Contracts.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,17 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace LINGYUN.Abp.TaskManagement.HttpApi.Client; |
||||
|
|
||||
|
[DependsOn(typeof(TaskManagementApplicationContractsModule))] |
||||
|
[DependsOn(typeof(AbpHttpClientModule))] |
||||
|
public class TaskManagementHttpApiClientModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddHttpClientProxies( |
||||
|
typeof(TaskManagementApplicationContractsModule).Assembly, |
||||
|
TaskManagementRemoteServiceConsts.RemoteServiceName); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue