每10秒更换一次状态

This commit is contained in:
马梓彭 2026-05-11 12:53:00 +08:00
parent ecd26989f1
commit 02bfea6e56

View File

@ -8,13 +8,14 @@ namespace YD_Event.Application.Event;
/// <summary>
/// 赛事状态自动更新后台服务
/// 每5分钟执行一次,自动更新赛事状态
/// 每10秒执行一次,自动更新赛事状态
/// </summary>
public class EventStatusUpdateService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<EventStatusUpdateService> _logger;
private readonly PeriodicTimer _timer;
private int _executionCount = 0;
public EventStatusUpdateService(
IServiceProvider serviceProvider,
@ -22,12 +23,12 @@ public class EventStatusUpdateService : BackgroundService
{
_serviceProvider = serviceProvider;
_logger = logger;
_timer = new PeriodicTimer(TimeSpan.FromMinutes(5));
_timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("赛事状态自动更新服务已启动,每5分钟执行一次");
_logger.LogInformation("赛事状态自动更新服务已启动,每10秒执行一次");
try
{
@ -57,12 +58,46 @@ public class EventStatusUpdateService : BackgroundService
var now = DateTime.Now;
var eventsToUpdate = new List<EventInfo>();
_executionCount++;
// 每执行6次(约1分钟)做一次全量检查,其他时候只检查时间窗口内的赛事
var isFullCheck = _executionCount % 6 == 1;
List<EventInfo> candidateEvents;
var allEvents = await repository.AsQueryable()
.Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable)
.ToListAsync(stoppingToken);
if (isFullCheck)
{
_logger.LogDebug("执行全量赛事状态检查...");
candidateEvents = await repository.AsQueryable()
.Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable)
.ToListAsync(stoppingToken);
}
else
{
// 优化查询:只查询可能需要更新状态的赛事
// 逻辑:只查询那些当前时间接近关键时间点(报名开始/结束、比赛开始/结束)的赛事
// 设置一个时间窗口:当前时间前后各1分钟,这样只会处理即将或刚发生状态变化的赛事
var timeWindow = TimeSpan.FromMinutes(1);
var windowStart = now.Add(-timeWindow);
var windowEnd = now.Add(timeWindow);
foreach (var evt in allEvents)
candidateEvents = await repository.AsQueryable()
.Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable)
.Where(e =>
// 报名开始时间在时间窗口内
(e.RegistrationStartTime >= windowStart && e.RegistrationStartTime <= windowEnd) ||
// 报名结束时间在时间窗口内
(e.RegistrationEndTime >= windowStart && e.RegistrationEndTime <= windowEnd) ||
// 比赛开始时间在时间窗口内
(e.MatchStartTime >= windowStart && e.MatchStartTime <= windowEnd) ||
// 比赛结束时间在时间窗口内
(e.MatchEndTime >= windowStart && e.MatchEndTime <= windowEnd)
)
.ToListAsync(stoppingToken);
}
foreach (var evt in candidateEvents)
{
var newStatus = CalculateEventStatus(evt, now);
if (evt.EventStatus != newStatus)