feat(worker): add ContinueTask routing to QueueService

This commit is contained in:
Mika Kuns
2026-04-14 14:04:28 +02:00
parent 6cb8012d82
commit adc5a16afc

View File

@@ -75,6 +75,31 @@ public sealed class QueueService : BackgroundService
} }
} }
public async Task<string> ContinueTask(string taskId, string followUpPrompt)
{
var task = await _taskRepo.GetByIdAsync(taskId)
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
if (task.Status == Data.Models.TaskStatus.Running)
throw new InvalidOperationException("Task is currently running.");
lock (_lock)
{
if (_overrideSlot is not null)
throw new InvalidOperationException("override slot busy");
var cts = new CancellationTokenSource();
_overrideSlot = new QueueSlotState { TaskId = taskId, StartedAt = DateTime.UtcNow, Cts = cts };
_ = RunContinueInSlotAsync(taskId, followUpPrompt, cts.Token).ContinueWith(_ =>
{
lock (_lock) { _overrideSlot = null; }
}, TaskScheduler.Default);
}
return taskId;
}
public bool CancelTask(string taskId) public bool CancelTask(string taskId)
{ {
lock (_lock) lock (_lock)
@@ -159,4 +184,17 @@ public sealed class QueueService : BackgroundService
_logger.LogError(ex, "Slot runner error for task {TaskId}", task.Id); _logger.LogError(ex, "Slot runner error for task {TaskId}", task.Id);
} }
} }
private async Task RunContinueInSlotAsync(string taskId, string followUpPrompt, CancellationToken ct)
{
try
{
_logger.LogInformation("Continuing task {TaskId} in override slot", taskId);
await _runner.ContinueAsync(taskId, followUpPrompt, "override", ct);
}
catch (Exception ex)
{
_logger.LogError(ex, "Continue runner error for task {TaskId}", taskId);
}
}
} }