fix(cv): sync operation terminal state
This commit is contained in:
@@ -249,6 +249,7 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
|
||||
cancellationToken);
|
||||
if (affected == 1 && !canRetry)
|
||||
{
|
||||
await SynchronizeCvRunAsync(operation, OperationStatuses.Failed, message, now, cancellationToken);
|
||||
db.UserNotifications.Add(CreateTerminalNotification(operation, OperationStatuses.Failed, now));
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
@@ -272,6 +273,7 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
|
||||
cancellationToken);
|
||||
if (cancelled == 1)
|
||||
{
|
||||
await SynchronizeCvRunAsync(operation, OperationStatuses.Cancelled, "CV processing was cancelled.", now, cancellationToken);
|
||||
db.UserNotifications.Add(CreateTerminalNotification(operation, OperationStatuses.Cancelled, now));
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
if (transaction is not null) await transaction.CommitAsync(cancellationToken);
|
||||
@@ -303,6 +305,7 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
|
||||
cancellationToken);
|
||||
if (affected == 1)
|
||||
{
|
||||
await SynchronizeCvRunAsync(operation, OperationStatuses.Cancelled, "CV processing was cancelled.", now, cancellationToken);
|
||||
db.UserNotifications.Add(CreateTerminalNotification(operation, OperationStatuses.Cancelled, now));
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
if (transaction is not null) await transaction.CommitAsync(cancellationToken);
|
||||
@@ -332,6 +335,7 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
|
||||
var existingNotification = await db.UserNotifications.FirstOrDefaultAsync(item => item.OperationId == operationId, cancellationToken);
|
||||
if (existingNotification is not null) db.UserNotifications.Remove(existingNotification);
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
await SynchronizeCvRunAsync(operation, OperationStatuses.Queued, null, UtcNow, cancellationToken);
|
||||
if (transaction is not null) await transaction.CommitAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
@@ -393,6 +397,7 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
|
||||
.SetProperty(item => item.LeaseExpiresAtUtc, (DateTime?)null), cancellationToken);
|
||||
if (affected == 1)
|
||||
{
|
||||
await SynchronizeCvRunAsync(operation, status, message, now, cancellationToken);
|
||||
db.UserNotifications.Add(CreateTerminalNotification(operation, status, now));
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
if (transaction is not null) await transaction.CommitAsync(cancellationToken);
|
||||
@@ -405,6 +410,43 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
|
||||
return await db.Database.BeginTransactionAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private Task<int> SynchronizeCvRunAsync(
|
||||
UserOperation operation,
|
||||
string operationStatus,
|
||||
string? message,
|
||||
DateTime now,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
if (!string.Equals(operation.TaskType, CvProcessingQueue.TaskType, StringComparison.Ordinal)
|
||||
|| !string.Equals(operation.SubjectType, CvProcessingQueue.SubjectType, StringComparison.Ordinal)
|
||||
|| !int.TryParse(operation.SubjectId, System.Globalization.NumberStyles.None,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out var runId)
|
||||
|| runId <= 0)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
var runStatus = operationStatus switch
|
||||
{
|
||||
OperationStatuses.Cancelled => "cancelled",
|
||||
OperationStatuses.Failed => "failed",
|
||||
OperationStatuses.Queued => "queued",
|
||||
_ => null,
|
||||
};
|
||||
if (runStatus is null) return Task.FromResult(0);
|
||||
var completedAt = OperationStatuses.IsTerminal(operationStatus)
|
||||
? new DateTimeOffset(DateTime.SpecifyKind(now, DateTimeKind.Utc))
|
||||
: (DateTimeOffset?)null;
|
||||
|
||||
return db.CvExtractionRuns.IgnoreQueryFilters()
|
||||
.Where(run => run.Id == runId && run.OwnerUserId == operation.OwnerUserId)
|
||||
.ExecuteUpdateAsync(setters => setters
|
||||
.SetProperty(run => run.Status, runStatus)
|
||||
.SetProperty(run => run.ErrorMessage, message)
|
||||
.SetProperty(run => run.CompletedAtUtc, completedAt),
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
private static UserNotification CreateTerminalNotification(UserOperation operation, string status, DateTime now)
|
||||
{
|
||||
var (kind, title, message) = status switch
|
||||
|
||||
Reference in New Issue
Block a user