每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> /// <summary>
/// 赛事状态自动更新后台服务 /// 赛事状态自动更新后台服务
/// 每5分钟执行一次,自动更新赛事状态 /// 每10秒执行一次,自动更新赛事状态
/// </summary> /// </summary>
public class EventStatusUpdateService : BackgroundService public class EventStatusUpdateService : BackgroundService
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ILogger<EventStatusUpdateService> _logger; private readonly ILogger<EventStatusUpdateService> _logger;
private readonly PeriodicTimer _timer; private readonly PeriodicTimer _timer;
private int _executionCount = 0;
public EventStatusUpdateService( public EventStatusUpdateService(
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
@ -22,12 +23,12 @@ public class EventStatusUpdateService : BackgroundService
{ {
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_logger = logger; _logger = logger;
_timer = new PeriodicTimer(TimeSpan.FromMinutes(5)); _timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
} }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
_logger.LogInformation("赛事状态自动更新服务已启动,每5分钟执行一次"); _logger.LogInformation("赛事状态自动更新服务已启动,每10秒执行一次");
try try
{ {
@ -58,11 +59,45 @@ public class EventStatusUpdateService : BackgroundService
var now = DateTime.Now; var now = DateTime.Now;
var eventsToUpdate = new List<EventInfo>(); var eventsToUpdate = new List<EventInfo>();
var allEvents = await repository.AsQueryable() _executionCount++;
.Where(e => !e.DeleteMark && e.Status == AvailabilityStatus.Enable)
.ToListAsync(stoppingToken);
foreach (var evt in allEvents) // 每执行6次(约1分钟)做一次全量检查,其他时候只检查时间窗口内的赛事
var isFullCheck = _executionCount % 6 == 1;
List<EventInfo> candidateEvents;
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);
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); var newStatus = CalculateEventStatus(evt, now);
if (evt.EventStatus != newStatus) if (evt.EventStatus != newStatus)