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