diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj index b87cec0b6..f46c407f6 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs.Hangfire/LINGYUN.Abp.BackgroundJobs.Hangfire.csproj @@ -3,6 +3,14 @@ netstandard2.0 + true + 2.9.0 + LINGYUN + + + + + D:\LocalNuget diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN.Abp.BackgroundJobs.csproj b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN.Abp.BackgroundJobs.csproj new file mode 100644 index 000000000..420f871a3 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN.Abp.BackgroundJobs.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.0 + + true + 2.9.0 + LINGYUN + + + + D:\LocalNuget + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN/Abp/BackgroundJobs/RetryAsyncBackgroundJobArgs.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN/Abp/BackgroundJobs/RetryAsyncBackgroundJobArgs.cs new file mode 100644 index 000000000..369ccaf12 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN/Abp/BackgroundJobs/RetryAsyncBackgroundJobArgs.cs @@ -0,0 +1,43 @@ +namespace LINGYUN.Abp.BackgroundJobs +{ + public class RetryAsyncBackgroundJobArgs + { + /// + /// 重试次数 + /// + public int RetryCount { get; set; } = 0; + /// + /// 重试间隔(毫秒) + /// 默认 300000ms = 5min + /// + public double RetryIntervalMillisecond { get; set; } = 300000d; + /// + /// 最大重试次数 + /// 默认 20 + /// + public int MaxRetryCount { get; set; } = 20; + /// + /// 作业参数 + /// + public TArgs JobArgs { get; set; } + + public RetryAsyncBackgroundJobArgs() + { + + } + + public RetryAsyncBackgroundJobArgs(TArgs jobArgs) + { + JobArgs = jobArgs; + } + + public RetryAsyncBackgroundJobArgs(TArgs jobArgs, int retryCount = 0, double interval = 300000d, int maxRetryCount = 20) + { + JobArgs = jobArgs; + + RetryCount = retryCount; + RetryIntervalMillisecond = interval; + MaxRetryCount = maxRetryCount; + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN/Abp/BackgroundJobs/RetryAsyncBackgroundJobBase.cs b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN/Abp/BackgroundJobs/RetryAsyncBackgroundJobBase.cs new file mode 100644 index 000000000..e309e8bbd --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.BackgroundJobs/LINGYUN/Abp/BackgroundJobs/RetryAsyncBackgroundJobBase.cs @@ -0,0 +1,80 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System; +using System.Threading.Tasks; +using Volo.Abp.BackgroundJobs; + +namespace LINGYUN.Abp.BackgroundJobs +{ + public abstract class RetryAsyncBackgroundJobBase : IAsyncBackgroundJob> + { + public ILogger> Logger { get; set; } + + protected IBackgroundJobManager BackgroundJobManager { get; } + + protected RetryAsyncBackgroundJobBase( + IBackgroundJobManager backgroundJobManager) + { + BackgroundJobManager = backgroundJobManager; + + Logger = NullLogger>.Instance; + } + + public async Task ExecuteAsync(RetryAsyncBackgroundJobArgs args) + { + if (args.RetryCount > args.MaxRetryCount) + { + Logger.LogWarning("Job has failed and the maximum number of retries has been reached. The failure callback is about to enter"); + // 任务执行失败次数已达上限,调用用户定义回调,并不再执行 + await OnJobExecuteFailedAsync(args.JobArgs); + return; + } + try + { + // 执行任务 + await ExecuteAsync(args.JobArgs, args.RetryCount); + // 执行完成后回调 + await OnJobExecuteCompletedAsync(args.JobArgs); + } + catch(Exception ex) + { + Logger.LogWarning("Job execution has failed and a retry is imminent"); + Logger.LogWarning("Job running error:{0}", ex.Message); + + // 每次重试 间隔时间增加1.1倍 + var retryInterval = args.RetryIntervalMillisecond * 1.1; + var retryJobArgs = new RetryAsyncBackgroundJobArgs(args.JobArgs, + args.RetryCount + 1, retryInterval, args.MaxRetryCount); + + Logger.LogDebug("Job task is queued for the next execution"); + + // 计算优先级 + BackgroundJobPriority priority = BackgroundJobPriority.Normal; + + if (args.RetryCount <= (args.MaxRetryCount / 2) && + args.RetryCount > (args.MaxRetryCount / 3)) + { + priority = BackgroundJobPriority.BelowNormal; + } + else if (args.RetryCount > (args.MaxRetryCount / 1.5)) + { + priority = BackgroundJobPriority.Low; + } + // 延迟入队,等待下一次运行 + await BackgroundJobManager.EnqueueAsync(retryJobArgs, priority, delay: TimeSpan.FromMilliseconds(retryInterval)); + } + } + + protected abstract Task ExecuteAsync(TArgs args, int retryCount); + + protected virtual Task OnJobExecuteFailedAsync(TArgs args) + { + return Task.CompletedTask; + } + + protected virtual Task OnJobExecuteCompletedAsync(TArgs args) + { + return Task.CompletedTask; + } + } +}