using JSMR.Application.Jobs; using JSMR.Domain.Entities; using JSMR.Domain.Enums; using Microsoft.EntityFrameworkCore; namespace JSMR.Infrastructure.Data.Repositories.Jobs; public sealed class JobRepository(AppDbContext dbContext) : IJobRepository { public async Task AddAsync(Job job, CancellationToken cancellationToken) { await dbContext.Jobs.AddAsync(job, cancellationToken); return job; } public Task GetByIdAsync(int id, CancellationToken cancellationToken) => dbContext.Jobs.FirstOrDefaultAsync(x => x.Id == id, cancellationToken); public async Task> GetRecentAsync(int take, CancellationToken cancellationToken) => await dbContext.Jobs .OrderByDescending(x => x.CreatedUtc) .Take(take) .ToListAsync(cancellationToken); public Task AnyRunningAsync(CancellationToken cancellationToken) => dbContext.Jobs.AnyAsync(x => x.Status == JobStatus.Running, cancellationToken); public async Task TryClaimNextQueuedAsync(string workerName, CancellationToken cancellationToken) { Job? next = await dbContext.Jobs .Where(x => x.Status == JobStatus.Queued) .OrderBy(x => x.CreatedUtc) .FirstOrDefaultAsync(cancellationToken); if (next is null) return null; next.Status = JobStatus.Running; next.StartedUtc = DateTime.UtcNow; next.HeartbeatUtc = DateTime.UtcNow; next.WorkerName = workerName; next.AttemptCount += 1; await dbContext.SaveChangesAsync(cancellationToken); return next; } public Task SaveChangesAsync(CancellationToken ct) => dbContext.SaveChangesAsync(ct); }