4 changed files with 150 additions and 0 deletions
@ -0,0 +1,19 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> |
|||
<Version>2.9.0</Version> |
|||
<Authors>LINGYUN</Authors> |
|||
</PropertyGroup> |
|||
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
|||
<OutputPath>D:\LocalNuget</OutputPath> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="2.9.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,43 @@ |
|||
namespace LINGYUN.Abp.BackgroundJobs |
|||
{ |
|||
public class RetryAsyncBackgroundJobArgs<TArgs> |
|||
{ |
|||
/// <summary>
|
|||
/// 重试次数
|
|||
/// </summary>
|
|||
public int RetryCount { get; set; } = 0; |
|||
/// <summary>
|
|||
/// 重试间隔(毫秒)
|
|||
/// 默认 300000ms = 5min
|
|||
/// </summary>
|
|||
public double RetryIntervalMillisecond { get; set; } = 300000d; |
|||
/// <summary>
|
|||
/// 最大重试次数
|
|||
/// 默认 20
|
|||
/// </summary>
|
|||
public int MaxRetryCount { get; set; } = 20; |
|||
/// <summary>
|
|||
/// 作业参数
|
|||
/// </summary>
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -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<TArgs> : IAsyncBackgroundJob<RetryAsyncBackgroundJobArgs<TArgs>> |
|||
{ |
|||
public ILogger<RetryAsyncBackgroundJobBase<TArgs>> Logger { get; set; } |
|||
|
|||
protected IBackgroundJobManager BackgroundJobManager { get; } |
|||
|
|||
protected RetryAsyncBackgroundJobBase( |
|||
IBackgroundJobManager backgroundJobManager) |
|||
{ |
|||
BackgroundJobManager = backgroundJobManager; |
|||
|
|||
Logger = NullLogger<RetryAsyncBackgroundJobBase<TArgs>>.Instance; |
|||
} |
|||
|
|||
public async Task ExecuteAsync(RetryAsyncBackgroundJobArgs<TArgs> 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<TArgs>(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; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue