Browse Source

Merge pull request #789 from colinin/tasks-specification

Tasks specification
pull/802/head
yx lin 3 years ago
committed by GitHub
parent
commit
492a1c40de
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs
  2. 38
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoExtensions.cs
  3. 36
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoSpecification.cs
  4. 19
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoWaitingPeriodSpecification.cs
  5. 21
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoWaitingSpecification.cs
  6. 9
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/IBackgroundJobInfoRepository.cs
  7. 32
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs
  8. 76
      aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs

5
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Application/LINGYUN/Abp/TaskManagement/BackgroundJobInfoAppService.cs

@ -142,9 +142,10 @@ public class BackgroundJobInfoAppService : DynamicQueryableAppService<Background
Status = input.Status,
Type = input.Type
};
var totalCount = await BackgroundJobInfoRepository.GetCountAsync(filter);
var specification = new BackgroundJobInfoSpecification(filter);
var totalCount = await BackgroundJobInfoRepository.GetCountAsync(specification);
var backgroundJobInfos = await BackgroundJobInfoRepository.GetListAsync(
filter, input.Sorting, input.MaxResultCount, input.SkipCount);
specification, input.Sorting, input.MaxResultCount, input.SkipCount);
return new PagedResultDto<BackgroundJobInfoDto>(totalCount,
ObjectMapper.Map<List<BackgroundJobInfo>, List<BackgroundJobInfoDto>>(backgroundJobInfos));

38
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoExtensions.cs

@ -0,0 +1,38 @@
using LINGYUN.Abp.BackgroundTasks;
namespace LINGYUN.Abp.TaskManagement;
public static class BackgroundJobInfoEbackgroundJobInfotensions
{
public static JobInfo ToJobInfo(this BackgroundJobInfo backgroundJobInfo)
{
return new JobInfo
{
Id = backgroundJobInfo.Id,
TenantId = backgroundJobInfo.TenantId,
Name = backgroundJobInfo.Name,
NextRunTime = backgroundJobInfo.NextRunTime,
Args = backgroundJobInfo.Args,
IsAbandoned = backgroundJobInfo.IsAbandoned,
BeginTime = backgroundJobInfo.BeginTime,
EndTime = backgroundJobInfo.EndTime,
CreationTime = backgroundJobInfo.CreationTime,
Cron = backgroundJobInfo.Cron,
MaxCount = backgroundJobInfo.MaxCount,
MaxTryCount = backgroundJobInfo.MaxTryCount,
Description = backgroundJobInfo.Description,
Group = backgroundJobInfo.Group,
Interval = backgroundJobInfo.Interval,
JobType = backgroundJobInfo.JobType,
Status = backgroundJobInfo.Status,
Priority = backgroundJobInfo.Priority,
Source = backgroundJobInfo.Source,
LastRunTime = backgroundJobInfo.LastRunTime,
LockTimeOut = backgroundJobInfo.LockTimeOut,
Result = backgroundJobInfo.Result,
TriggerCount = backgroundJobInfo.TriggerCount,
TryCount = backgroundJobInfo.TryCount,
Type = backgroundJobInfo.Type,
NodeName = backgroundJobInfo.NodeName,
};
}
}

36
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoSpecification.cs

@ -0,0 +1,36 @@
using System;
using System.Linq.Expressions;
using Volo.Abp.Specifications;
namespace LINGYUN.Abp.TaskManagement;
public class BackgroundJobInfoSpecification : Specification<BackgroundJobInfo>
{
protected BackgroundJobInfoFilter Filter { get; }
public BackgroundJobInfoSpecification(BackgroundJobInfoFilter filter)
{
Filter = filter;
}
public override Expression<Func<BackgroundJobInfo, bool>> ToExpression()
{
Expression<Func<BackgroundJobInfo, bool>> expression = _ => true;
return expression
.AndIf(!Filter.Type.IsNullOrWhiteSpace(), x => x.Type.Contains(Filter.Type))
.AndIf(!Filter.Group.IsNullOrWhiteSpace(), x => x.Group.Equals(Filter.Group))
.AndIf(!Filter.Name.IsNullOrWhiteSpace(), x => x.Name.Equals(Filter.Name))
.AndIf(!Filter.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(Filter.Filter) ||
x.Group.Contains(Filter.Filter) || x.Type.Contains(Filter.Filter) || x.Description.Contains(Filter.Filter))
.AndIf(Filter.JobType.HasValue, x => x.JobType == Filter.JobType)
.AndIf(Filter.Status.HasValue, x => x.Status == Filter.Status.Value)
.AndIf(Filter.Priority.HasValue, x => x.Priority == Filter.Priority.Value)
.AndIf(Filter.Source.HasValue, x => x.Source == Filter.Source.Value)
.AndIf(Filter.IsAbandoned.HasValue, x => x.IsAbandoned == Filter.IsAbandoned.Value)
.AndIf(Filter.BeginLastRunTime.HasValue, x => x.LastRunTime >= Filter.BeginLastRunTime)
.AndIf(Filter.EndLastRunTime.HasValue, x => x.LastRunTime <= Filter.EndLastRunTime)
.AndIf(Filter.BeginTime.HasValue, x => x.BeginTime >= Filter.BeginTime)
.AndIf(Filter.EndTime.HasValue, x => x.EndTime <= Filter.EndTime)
.AndIf(Filter.BeginCreationTime.HasValue, x => x.CreationTime >= Filter.BeginCreationTime)
.AndIf(Filter.EndCreationTime.HasValue, x => x.CreationTime <= Filter.EndCreationTime);
}
}

19
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoWaitingPeriodSpecification.cs

@ -0,0 +1,19 @@
using LINGYUN.Abp.BackgroundTasks;
using System;
using System.Linq;
using System.Linq.Expressions;
namespace LINGYUN.Abp.TaskManagement;
public class BackgroundJobInfoWaitingPeriodSpecification : BackgroundJobInfoWaitingSpecification
{
public override Expression<Func<BackgroundJobInfo, bool>> ToExpression()
{
var status = new JobStatus[] { JobStatus.Running, JobStatus.FailedRetry };
Expression<Func<BackgroundJobInfo, bool>> expression = _ => true;
return expression
.And(x => x.IsEnabled && !x.IsAbandoned)
.And(x => x.JobType == JobType.Period && status.Contains(x.Status))
.And(x => (x.MaxCount == 0 || x.TriggerCount < x.MaxCount) || (x.MaxTryCount == 0 || x.TryCount < x.MaxTryCount));
}
}

21
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/BackgroundJobInfoWaitingSpecification.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.BackgroundTasks;
using System;
using System.Linq;
using System.Linq.Expressions;
namespace LINGYUN.Abp.TaskManagement;
public class BackgroundJobInfoWaitingSpecification : Volo.Abp.Specifications.Specification<BackgroundJobInfo>
{
public override Expression<Func<BackgroundJobInfo, bool>> ToExpression()
{
var status = new JobStatus[] { JobStatus.Running, JobStatus.FailedRetry };
Expression<Func<BackgroundJobInfo, bool>> expression = _ => true;
return expression
.And(x => x.IsEnabled && !x.IsAbandoned)
.And(x => x.JobType != JobType.Period && status.Contains(x.Status))
.And(x => (x.MaxCount == 0 || x.TriggerCount < x.MaxCount) || (x.MaxTryCount == 0 || x.TryCount < x.MaxTryCount));
}
}

9
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/LINGYUN/Abp/TaskManagement/IBackgroundJobInfoRepository.cs

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Specifications;
namespace LINGYUN.Abp.TaskManagement;
@ -54,23 +55,23 @@ public interface IBackgroundJobInfoRepository : IRepository<BackgroundJobInfo, s
/// <summary>
/// 获取过滤后的任务数量
/// </summary>
/// <param name="filter"></param>
/// <param name="specification">查询规约</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<int> GetCountAsync(
BackgroundJobInfoFilter filter,
ISpecification<BackgroundJobInfo> specification,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取过滤后的任务列表
/// </summary>
/// <param name="filter"></param>
/// <param name="specification">查询规约</param>
/// <param name="sorting"></param>
/// <param name="maxResultCount"></param>
/// <param name="skipCount"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<List<BackgroundJobInfo>> GetListAsync(
BackgroundJobInfoFilter filter,
ISpecification<BackgroundJobInfo> specification,
string sorting = nameof(BackgroundJobInfo.Name),
int maxResultCount = 10,
int skipCount = 0,

32
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.Domain/System/Linq/Expressions/ExpressionFuncExtensions.cs

@ -0,0 +1,32 @@
using Volo.Abp.Specifications;
namespace System.Linq.Expressions;
internal static class ExpressionFuncExtensions
{
public static Expression<Func<T, bool>> AndIf<T>(
this Expression<Func<T, bool>> first,
bool condition,
Expression<Func<T, bool>> second)
{
if (condition)
{
return ExpressionFuncExtender.And(first, second);
}
return first;
}
public static Expression<Func<T, bool>> OrIf<T>(
this Expression<Func<T, bool>> first,
bool condition,
Expression<Func<T, bool>> second)
{
if (condition)
{
return ExpressionFuncExtender.Or(first, second);
}
return first;
}
}

76
aspnet-core/modules/task-management/LINGYUN.Abp.TaskManagement.EntityFrameworkCore/LINGYUN/Abp/TaskManagement/EntityFrameworkCore/EfCoreBackgroundJobInfoRepository.cs

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Specifications;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.TaskManagement.EntityFrameworkCore;
@ -43,35 +44,7 @@ public class EfCoreBackgroundJobInfoRepository :
{
return await (await GetDbSetAsync())
.Where(x => x.Id.Equals(id))
.Select(x => new JobInfo
{
Id = x.Id,
TenantId = x.TenantId,
Name = x.Name,
NextRunTime = x.NextRunTime,
Args = x.Args,
IsAbandoned = x.IsAbandoned,
BeginTime = x.BeginTime,
EndTime = x.EndTime,
CreationTime = x.CreationTime,
Cron = x.Cron,
MaxCount = x.MaxCount,
MaxTryCount = x.MaxTryCount,
Description = x.Description,
Group = x.Group,
Interval = x.Interval,
JobType = x.JobType,
Status = x.Status,
Priority = x.Priority,
Source = x.Source,
LastRunTime = x.LastRunTime,
LockTimeOut = x.LockTimeOut,
Result = x.Result,
TriggerCount = x.TriggerCount,
TryCount = x.TryCount,
Type = x.Type,
NodeName = x.NodeName,
})
.Select(x => x.ToJobInfo())
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
}
@ -92,26 +65,24 @@ public class EfCoreBackgroundJobInfoRepository :
public async virtual Task<List<BackgroundJobInfo>> GetAllPeriodTasksAsync(
CancellationToken cancellationToken = default)
{
var status = new JobStatus[] { JobStatus.Running, JobStatus.FailedRetry };
return await (await GetDbSetAsync())
.Where(x => x.IsEnabled && !x.IsAbandoned)
.Where(x => x.JobType == JobType.Period && status.Contains(x.Status))
.Where(x => (x.MaxCount == 0 || x.TriggerCount < x.MaxCount) || (x.MaxTryCount == 0 || x.TryCount < x.MaxTryCount))
.Where(new BackgroundJobInfoWaitingPeriodSpecification().ToExpression())
.OrderByDescending(x => x.Priority)
.AsNoTracking()
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async virtual Task<int> GetCountAsync(BackgroundJobInfoFilter filter, CancellationToken cancellationToken = default)
public async virtual Task<int> GetCountAsync(ISpecification<BackgroundJobInfo> specification, CancellationToken cancellationToken = default)
{
return await ApplyFilter(await GetDbSetAsync(), filter)
return await (await GetDbSetAsync())
.Where(specification.ToExpression())
.CountAsync(GetCancellationToken(cancellationToken));
}
public async virtual Task<List<BackgroundJobInfo>> GetListAsync(BackgroundJobInfoFilter filter, string sorting = "Name", int maxResultCount = 10, int skipCount = 0, CancellationToken cancellationToken = default)
public async virtual Task<List<BackgroundJobInfo>> GetListAsync(ISpecification<BackgroundJobInfo> specification, string sorting = "Name", int maxResultCount = 10, int skipCount = 0, CancellationToken cancellationToken = default)
{
return await ApplyFilter(await GetDbSetAsync(), filter)
return await (await GetDbSetAsync())
.Where(specification.ToExpression())
.OrderBy(sorting ?? $"{nameof(BackgroundJobInfo.CreationTime)} DESC")
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
@ -121,12 +92,8 @@ public class EfCoreBackgroundJobInfoRepository :
int maxResultCount,
CancellationToken cancellationToken = default)
{
var status = new JobStatus[] { JobStatus.Running, JobStatus.FailedRetry };
return await (await GetDbSetAsync())
.Where(x => x.IsEnabled && !x.IsAbandoned)
.Where(x => x.JobType != JobType.Period && status.Contains(x.Status))
.Where(x => (x.MaxCount == 0 || x.TriggerCount < x.MaxCount) || (x.MaxTryCount == 0 || x.TryCount < x.MaxTryCount))
.Where(new BackgroundJobInfoWaitingSpecification().ToExpression())
.OrderByDescending(x => x.Priority)
.ThenBy(x => x.TryCount)
.ThenBy(x => x.NextRunTime)
@ -134,27 +101,4 @@ public class EfCoreBackgroundJobInfoRepository :
.AsNoTracking()
.ToListAsync(GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<BackgroundJobInfo> ApplyFilter(
IQueryable<BackgroundJobInfo> queryable,
BackgroundJobInfoFilter filter)
{
return queryable
.WhereIf(!filter.Type.IsNullOrWhiteSpace(), x => x.Type.Contains(filter.Type))
.WhereIf(!filter.Group.IsNullOrWhiteSpace(), x => x.Group.Equals(filter.Group))
.WhereIf(!filter.Name.IsNullOrWhiteSpace(), x => x.Name.Equals(filter.Name))
.WhereIf(!filter.Filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter.Filter) ||
x.Group.Contains(filter.Filter) || x.Type.Contains(filter.Filter) || x.Description.Contains(filter.Filter))
.WhereIf(filter.JobType.HasValue, x => x.JobType == filter.JobType)
.WhereIf(filter.Status.HasValue, x => x.Status == filter.Status.Value)
.WhereIf(filter.Priority.HasValue, x => x.Priority == filter.Priority.Value)
.WhereIf(filter.Source.HasValue, x => x.Source == filter.Source.Value)
.WhereIf(filter.IsAbandoned.HasValue, x => x.IsAbandoned == filter.IsAbandoned.Value)
.WhereIf(filter.BeginLastRunTime.HasValue, x => filter.BeginLastRunTime.Value.CompareTo(x.LastRunTime) <= 0)
.WhereIf(filter.EndLastRunTime.HasValue, x => filter.EndLastRunTime.Value.CompareTo(x.LastRunTime) >= 0)
.WhereIf(filter.BeginTime.HasValue, x => x.BeginTime.CompareTo(x.BeginTime) >= 0)
.WhereIf(filter.EndTime.HasValue, x => filter.EndTime.Value.CompareTo(x.EndTime) >= 0)
.WhereIf(filter.BeginCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.BeginCreationTime.Value) >= 0)
.WhereIf(filter.EndCreationTime.HasValue, x => x.CreationTime.CompareTo(filter.EndCreationTime.Value) <= 0);
}
}

Loading…
Cancel
Save