每10秒更换一次状态
This commit is contained in:
parent
ecd26989f1
commit
02bfea6e56
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user