LMS.service/LMS.Tools/MJPackage/TaskStatusCheckService.cs

132 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using LMS.Common.Extensions;
using LMS.DAO;
using LMS.Repository.DB;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Quartz;
namespace LMS.Tools.MJPackage
{
[DisallowConcurrentExecution]
public class TaskStatusCheckService(ITokenService tokenService, ApplicationDbContext dbContext, ILogger<TaskStatusCheckService> logger, ITaskService taskService, ITaskConcurrencyManager taskConcurrencyManager, TokenUsageTracker tokenUsageTracker) : IJob
{
private readonly ITokenService _tokenService = tokenService;
private readonly ApplicationDbContext _dbContext = dbContext;
private readonly ILogger<TaskStatusCheckService> _logger = logger;
private readonly ITaskService _taskService = taskService;
private readonly ITaskConcurrencyManager _taskConcurrencyManager = taskConcurrencyManager;
private readonly TokenUsageTracker _tokenUsageTracker = tokenUsageTracker;
public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation($"开始检查TASK信息 - 检查间隔: 5 分钟,同步加载 原始请求的Token");
var startTime = BeijingTimeExtension.GetBeijingTime();
try
{
// 强制同步数据库数据原请求Token
await _tokenService.LoadOriginTokenAsync();
// 强制同步数据 MJ API 的 Basic URL
await _tokenService.LoadMJAPIBasicUrlAsync();
// 检查Task状态和返回值
// 获取所有超过五分钟没有完成的人物
List<MJApiTasks> tasks = await _dbContext.MJApiTasks.Where(t => t.Status != MJTaskStatus.CANCEL && t.Status != MJTaskStatus.SUCCESS && t.Status != MJTaskStatus.FAILURE && t.StartTime < BeijingTimeExtension.GetBeijingTime().AddMinutes(-5)).ToListAsync();
if (tasks.Count == 0)
{
_logger.LogInformation("没有需要检查的任务!");
return;
}
// 开始每个请求
foreach (MJApiTasks task in tasks)
{
try
{
Dictionary<string, object>? properties = await _taskService.FetchTaskAsync(task);
// 没有找到数据的
if (properties == null)
{
// 没有找到数据 直接把任务失败
task.Status = MJTaskStatus.FAILURE;
var newProperties = new
{
failReason = "任务丢失或未找到"
};
task.EndTime = BeijingTimeExtension.GetBeijingTime();
task.Properties = JsonConvert.SerializeObject(newProperties);
// 尝试释放 当前缓存中的任务
_tokenUsageTracker.RemoveTaskCache(task.ThirdPartyTaskId);
_logger.LogWarning("任务轮询检查未请求到对应的MJ数据释放Token释放任务" + task.Token);
_tokenUsageTracker.ReleaseConcurrencyPermit(task.Token);
}
else
{
// 尝试获取状态字段
string status = MJTaskStatus.SUBMITTED;
if (properties.TryGetValue("status", out var statusElement))
{
status = statusElement.ToString() ?? MJTaskStatus.SUBMITTED;
}
else if (properties.TryGetValue("Status", out var statusElementCap))
{
status = statusElementCap.ToString() ?? MJTaskStatus.SUBMITTED;
}
task.Status = status;
if (status == MJTaskStatus.SUCCESS || status == MJTaskStatus.FAILURE || status == MJTaskStatus.CANCEL)
{
// 当前任务已经被释放过了
// 开始修改数据
task.EndTime = BeijingTimeExtension.GetBeijingTime();
task.Properties = JsonConvert.SerializeObject(properties);
_logger.LogInformation("任务轮询检查已请求到对应的MJ数据并且状态为成功失败取消释放Token释放任务" + task.Token);
_tokenUsageTracker.ReleaseConcurrencyPermit(task.Token);
// 尝试释放 当前缓存中的任务
_tokenUsageTracker.RemoveTaskCache(task.ThirdPartyTaskId);
}
else
{
// 任务还在处理中
task.EndTime = null; // 处理中没有结束时间
task.Properties = JsonConvert.SerializeObject(properties);
}
}
// 开始修改数据
await _taskConcurrencyManager.UpdateTaskInDatabase(task);
}
catch (Exception ex)
{
// 报错
_logger.LogError(ex, $"检查任务 {task.Token} 时发生错误释放Token释放任务", task.TaskId);
task.Status = MJTaskStatus.FAILURE;
var newProperties = new
{
failReason = "任务报错"
};
task.EndTime = BeijingTimeExtension.GetBeijingTime();
task.Properties = JsonConvert.SerializeObject(newProperties);
_tokenUsageTracker.ReleaseConcurrencyPermit(task.Token);
// 尝试释放 当前缓存中的任务
_tokenUsageTracker.RemoveTaskCache(task.ThirdPartyTaskId);
// 开始修改数据
await _taskConcurrencyManager.UpdateTaskInDatabase(task);
}
}
var duration = BeijingTimeExtension.GetBeijingTime() - startTime;
_logger.LogInformation($"Task状态检查完成影响的Task {tasks.Count},耗时: {duration}ms", duration.TotalMilliseconds);
}
catch (Exception ex)
{
var duration = BeijingTimeExtension.GetBeijingTime() - startTime;
_logger.LogError(ex, "Token同步失败耗时: {Duration}ms", duration.TotalMilliseconds);
}
}
}
}