52 lines
1.7 KiB
C#
52 lines
1.7 KiB
C#
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<Job> AddAsync(Job job, CancellationToken cancellationToken)
|
|
{
|
|
await dbContext.Jobs.AddAsync(job, cancellationToken);
|
|
|
|
return job;
|
|
}
|
|
|
|
public Task<Job?> GetByIdAsync(int id, CancellationToken cancellationToken)
|
|
=> dbContext.Jobs.FirstOrDefaultAsync(x => x.Id == id, cancellationToken);
|
|
|
|
public async Task<IReadOnlyList<Job>> GetRecentAsync(int take, CancellationToken cancellationToken)
|
|
=> await dbContext.Jobs
|
|
.OrderByDescending(x => x.CreatedUtc)
|
|
.Take(take)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
public Task<bool> AnyRunningAsync(CancellationToken cancellationToken)
|
|
=> dbContext.Jobs.AnyAsync(x => x.Status == JobStatus.Running, cancellationToken);
|
|
|
|
public async Task<Job?> 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);
|
|
} |