feat(dal,api): IMatchingStatusService - управление статусами matcher`a. Отображение статусов в АПИ, нельзя повторно из апи отправить задание мэтчеру если сейчас идет matching
This commit is contained in:
@@ -6,9 +6,9 @@ namespace PARR.DAL.Cache.Models
|
||||
/// <summary>
|
||||
/// КЭШ модель, состояние matching`a
|
||||
/// </summary>
|
||||
public class MatchingStatus : IBaseCache<MatchingStatusDto>
|
||||
public class MatchingStatusItem : IBaseCache<MatchingStatusItemDto>
|
||||
{
|
||||
public required MatchingStatusDto Data { get; set; }
|
||||
public required MatchingStatusItemDto Data { get; set; }
|
||||
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace PARR.DAL.Cache.Models
|
||||
}
|
||||
|
||||
|
||||
public class MatchingStatusDto
|
||||
public class MatchingStatusItemDto
|
||||
{
|
||||
public DateTimeOffset DateStart { get; set; }
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
using PARR.Constants;
|
||||
using PARR.DAL.Cache.Models;
|
||||
using PARR.DAL.Cache.Services.Base;
|
||||
|
||||
namespace PARR.DAL.Cache.Services
|
||||
{
|
||||
internal class CacheMatchingStatusService : ICacheMatchingStatusService
|
||||
{
|
||||
private readonly IRedisCacheService redisCacheService;
|
||||
|
||||
public CacheMatchingStatusService(IRedisCacheService redisCacheService)
|
||||
{
|
||||
this.redisCacheService = redisCacheService;
|
||||
}
|
||||
|
||||
public async Task DeleteCacheAsync(Guid id, SyncTaskEntityTypeEnum type)
|
||||
{
|
||||
var key = GetKey(id, type);
|
||||
|
||||
await redisCacheService.DeleteCachedDataAsync(key);
|
||||
}
|
||||
|
||||
|
||||
public async Task<MatchingStatus?> GetDataAsync(Guid id, SyncTaskEntityTypeEnum type)
|
||||
{
|
||||
var key = GetKey(id, type);
|
||||
|
||||
return await redisCacheService.GetCachedDataAsync<MatchingStatus>(key);
|
||||
}
|
||||
|
||||
|
||||
public async Task SetCacheAsync(Guid id, SyncTaskEntityTypeEnum type, MatchingStatusDto data, TimeSpan cacheDuration)
|
||||
{
|
||||
var key = GetKey(id, type);
|
||||
|
||||
await redisCacheService.SetCachedDataAsync(key, data, cacheDuration);
|
||||
}
|
||||
|
||||
|
||||
private string GetKey(Guid id, SyncTaskEntityTypeEnum type)
|
||||
{
|
||||
var typeStr = "";
|
||||
switch (type)
|
||||
{
|
||||
case SyncTaskEntityTypeEnum.Job:
|
||||
typeStr = "j";
|
||||
break;
|
||||
case SyncTaskEntityTypeEnum.JobGroup:
|
||||
typeStr = "g";
|
||||
break;
|
||||
case SyncTaskEntityTypeEnum.Template:
|
||||
typeStr = "t";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return redisCacheService.GetKey(new string[] { "ms", typeStr, id.ToString() });
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using PARR.Constants;
|
||||
using PARR.DAL.Cache.Models;
|
||||
|
||||
namespace PARR.DAL.Cache.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Сервис - статус matching`a
|
||||
/// </summary>
|
||||
public interface ICacheMatchingStatusService
|
||||
{
|
||||
Task<MatchingStatus?> GetDataAsync(Guid id, SyncTaskEntityTypeEnum type);
|
||||
|
||||
Task SetCacheAsync(Guid id, SyncTaskEntityTypeEnum type, MatchingStatusDto data, TimeSpan cacheDuration);
|
||||
|
||||
Task DeleteCacheAsync(Guid id, SyncTaskEntityTypeEnum type);
|
||||
|
||||
}
|
||||
}
|
||||
36
PARR.DAL/DomainModels/MatchingStatus.cs
Normal file
36
PARR.DAL/DomainModels/MatchingStatus.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using PARR.DAL.Cache.Models;
|
||||
|
||||
namespace PARR.DAL.DomainModels
|
||||
{
|
||||
/// <summary>
|
||||
/// Статус matching`a
|
||||
/// </summary>
|
||||
public class MatchingStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// В целом по искомому объекту, идет ли matching
|
||||
/// </summary>
|
||||
public bool IsMatchingObject => IsMatchingJobs || IsMatchingJobGroups;
|
||||
|
||||
/// <summary>
|
||||
/// Идет ли мэтчинг по Jobs
|
||||
/// </summary>
|
||||
public bool IsMatchingJobs => DetailsJobs?.Any() ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Идет ли мэтчинг по JobGroups
|
||||
/// </summary>
|
||||
public bool IsMatchingJobGroups => DetailsJobGroups?.Any() ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Детально из КЭШ по Jobs
|
||||
/// </summary>
|
||||
public List<MatchingStatusItem>? DetailsJobs { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Детально из КЭШ по JobGroups
|
||||
/// </summary>
|
||||
public List<MatchingStatusItem>? DetailsJobGroups { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
120
PARR.DAL/DomainServices/Implementations/MatchingStatusService.cs
Normal file
120
PARR.DAL/DomainServices/Implementations/MatchingStatusService.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PARR.Constants;
|
||||
using PARR.DAL.Cache.Models;
|
||||
using PARR.DAL.Cache.Services.Base;
|
||||
using PARR.DAL.DomainModels;
|
||||
using PARR.DAL.DomainServices.Interfaces;
|
||||
using PARR.DAL.Services.Interfaces.Job;
|
||||
|
||||
namespace PARR.DAL.DomainServices.Implementations
|
||||
{
|
||||
internal class MatchingStatusService : IMatchingStatusService
|
||||
{
|
||||
private readonly IRedisCacheService redisCacheService;
|
||||
private readonly IJobService jobService;
|
||||
private readonly IJobGroupService jobGroupService;
|
||||
|
||||
public MatchingStatusService(
|
||||
IRedisCacheService redisCacheService,
|
||||
IJobService jobService,
|
||||
IJobGroupService jobGroupService
|
||||
)
|
||||
{
|
||||
this.redisCacheService = redisCacheService;
|
||||
this.jobService = jobService;
|
||||
this.jobGroupService = jobGroupService;
|
||||
}
|
||||
|
||||
|
||||
public async Task DeleteMatchingStatusAsync(Guid objectId, SyncTaskEntityTypeEnum type)
|
||||
{
|
||||
var key = GetKey(objectId, type);
|
||||
await redisCacheService.DeleteCachedDataAsync(key);
|
||||
}
|
||||
|
||||
public async Task<MatchingStatus> GetStatusAsync(Guid objectId, SyncTaskEntityTypeEnum type)
|
||||
{
|
||||
var jobGroupIdList = new List<Guid>();
|
||||
var jobIdList = new List<Guid>();
|
||||
|
||||
//формируем список jobId и jobGroupId для поиска в КЭШ, происходит ли у кого-то из них сейчас matching
|
||||
switch (type)
|
||||
{
|
||||
case SyncTaskEntityTypeEnum.Job:
|
||||
var job = await jobService.Get().FirstOrDefaultAsync(t => t.Id == objectId);
|
||||
if (job != null)
|
||||
{
|
||||
jobIdList.Add(job.Id);
|
||||
jobGroupIdList = await jobGroupService.Get().Where(t => t.Id == job.GroupId).Select(t => t.Id).ToListAsync();
|
||||
}
|
||||
break;
|
||||
case SyncTaskEntityTypeEnum.JobGroup:
|
||||
var jobGroup = await jobGroupService.Get().FirstOrDefaultAsync(t => t.Id == objectId);
|
||||
if (jobGroup != null)
|
||||
{
|
||||
jobGroupIdList.Add(jobGroup.Id);
|
||||
jobIdList = await jobService.Get().Where(t => t.GroupId == jobGroup.Id).Select(t => t.Id).ToListAsync();
|
||||
}
|
||||
break;
|
||||
case SyncTaskEntityTypeEnum.Template:
|
||||
throw new Exception("Нет реализации получения кэша статуса matching для template");
|
||||
//todo: У нас вообще нет matching для Template, позже надо удалить это вообще из Enum SyncTaskEntityTypeEnum
|
||||
break;
|
||||
}
|
||||
|
||||
// Если списки пустые, мало ли, говорим что нет matching`a
|
||||
if (!jobGroupIdList.Any() && !jobIdList.Any())
|
||||
return new MatchingStatus { DetailsJobGroups = null, DetailsJobs = null };
|
||||
|
||||
// Ищем в КЭШ
|
||||
var jobGroupDetails = new List<MatchingStatusItem>();
|
||||
foreach (var jobGroupId in jobGroupIdList)
|
||||
{
|
||||
var cacheResult = await redisCacheService.GetCachedDataAsync<MatchingStatusItem>(GetKey(jobGroupId, SyncTaskEntityTypeEnum.JobGroup));
|
||||
if (cacheResult != null)
|
||||
jobGroupDetails.Add(cacheResult);
|
||||
}
|
||||
|
||||
var jobDetails = new List<MatchingStatusItem>();
|
||||
foreach (var jobId in jobIdList)
|
||||
{
|
||||
var cacheResult = await redisCacheService.GetCachedDataAsync<MatchingStatusItem>(GetKey(jobId, SyncTaskEntityTypeEnum.Job));
|
||||
if (cacheResult != null)
|
||||
jobDetails.Add(cacheResult);
|
||||
}
|
||||
|
||||
return new MatchingStatus
|
||||
{
|
||||
DetailsJobGroups = jobGroupDetails.Any() ? jobGroupDetails : null,
|
||||
DetailsJobs = jobDetails.Any() ? jobDetails : null
|
||||
};
|
||||
}
|
||||
|
||||
public async Task SetMatchingStatusAsync(Guid objectId, SyncTaskEntityTypeEnum type, MatchingStatusItem data, TimeSpan cacheDuration)
|
||||
{
|
||||
var key = GetKey(objectId, type);
|
||||
await redisCacheService.SetCachedDataAsync(key, data, cacheDuration);
|
||||
}
|
||||
|
||||
private string GetKey(Guid id, SyncTaskEntityTypeEnum type)
|
||||
{
|
||||
var typeStr = "";
|
||||
switch (type)
|
||||
{
|
||||
case SyncTaskEntityTypeEnum.Job:
|
||||
typeStr = "j";
|
||||
break;
|
||||
case SyncTaskEntityTypeEnum.JobGroup:
|
||||
typeStr = "g";
|
||||
break;
|
||||
case SyncTaskEntityTypeEnum.Template:
|
||||
typeStr = "t";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return redisCacheService.GetKey(new string[] { "ms", typeStr, id.ToString() });
|
||||
}
|
||||
}
|
||||
}
|
||||
38
PARR.DAL/DomainServices/Interfaces/IMatchingStatusService.cs
Normal file
38
PARR.DAL/DomainServices/Interfaces/IMatchingStatusService.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using PARR.Constants;
|
||||
using PARR.DAL.Cache.Models;
|
||||
using PARR.DAL.DomainModels;
|
||||
|
||||
namespace PARR.DAL.DomainServices.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Сервис по управлению статусом Matching`a
|
||||
/// </summary>
|
||||
public interface IMatchingStatusService
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить статус matching`a
|
||||
/// </summary>
|
||||
/// <param name="objectId"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
Task<MatchingStatus> GetStatusAsync(Guid objectId, SyncTaskEntityTypeEnum type);
|
||||
|
||||
/// <summary>
|
||||
/// Установить/обновить статус matching`a
|
||||
/// </summary>
|
||||
/// <param name="objectId"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="cacheDuration"></param>
|
||||
/// <returns></returns>
|
||||
Task SetMatchingStatusAsync(Guid objectId, SyncTaskEntityTypeEnum type, MatchingStatusItem data, TimeSpan cacheDuration);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить статус matching`a
|
||||
/// </summary>
|
||||
/// <param name="objectId"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
Task DeleteMatchingStatusAsync(Guid objectId, SyncTaskEntityTypeEnum type);
|
||||
}
|
||||
}
|
||||
@@ -53,8 +53,6 @@ namespace PARR.DAL
|
||||
|
||||
services.AddTransient<IRedisCacheService, RedisCacheService>();
|
||||
|
||||
services.AddTransient<ICacheMatchingStatusService, CacheMatchingStatusService>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region InfluxDb
|
||||
@@ -141,6 +139,7 @@ namespace PARR.DAL
|
||||
#region DomainServces
|
||||
services.AddTransient<IShortcodesService, ShortcodesService>();
|
||||
services.AddTransient<IUnitFilterService, UnitFilterService>();
|
||||
services.AddTransient<IMatchingStatusService, MatchingStatusService>();
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user