refactor(worker): simplify ClaudeProcess to accept pre-built args and use StreamAnalyzer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mika Kuns
2026-04-14 11:45:23 +02:00
parent 8825351526
commit 1cdaaf9fd2
4 changed files with 50 additions and 34 deletions

View File

@@ -43,7 +43,7 @@ public sealed class QueueServiceTests : IDisposable
}
private (QueueService service, FakeClaudeProcess fakeProcess) CreateService(
Func<string, string, string, string, Func<string, Task>, CancellationToken, Task<RunResult>>? handler = null)
Func<string, string, string, Func<string, Task>, CancellationToken, Task<RunResult>>? handler = null)
{
var fake = new FakeClaudeProcess(handler);
var broadcaster = new HubBroadcaster(new FakeHubContext());
@@ -88,7 +88,7 @@ public sealed class QueueServiceTests : IDisposable
var (listId, _) = await SeedListWithAgentTag();
var tcs = new TaskCompletionSource<RunResult>();
var (service, _) = CreateService((_, _, _, _, _, ct) => tcs.Task);
var (service, _) = CreateService((_, _, _, _, ct) => tcs.Task);
var task1 = await SeedQueuedTask(listId);
var task2 = await SeedQueuedTask(listId);
@@ -114,7 +114,7 @@ public sealed class QueueServiceTests : IDisposable
var (listId, _) = await SeedListWithAgentTag();
await SeedQueuedTask(listId, scheduledFor: DateTime.UtcNow.AddHours(1));
var (service, fake) = CreateService((_, _, _, _, _, _) =>
var (service, fake) = CreateService((_, _, _, _, _) =>
Task.FromResult(new RunResult { ExitCode = 0, ResultMarkdown = "ok" }));
using var cts = new CancellationTokenSource();
@@ -139,17 +139,17 @@ public sealed class QueueServiceTests : IDisposable
var gate2 = new TaskCompletionSource();
var callCount = 0;
var (service, _) = CreateService(async (prompt, _, _, taskId, _, ct) =>
var (service, _) = CreateService(async (_, _, _, _, ct) =>
{
var n = Interlocked.Increment(ref callCount);
lock (order) { order.Add(taskId); }
lock (order) { order.Add(n.ToString()); }
if (n == 1) await gate1.Task;
if (n == 2) gate2.SetResult();
return new RunResult { ExitCode = 0, ResultMarkdown = "ok" };
});
var task1 = await SeedQueuedTask(listId, createdAt: DateTime.UtcNow.AddSeconds(-2));
var task2 = await SeedQueuedTask(listId, createdAt: DateTime.UtcNow.AddSeconds(-1));
await SeedQueuedTask(listId, createdAt: DateTime.UtcNow.AddSeconds(-2));
await SeedQueuedTask(listId, createdAt: DateTime.UtcNow.AddSeconds(-1));
using var cts = new CancellationTokenSource();
await service.StartAsync(cts.Token);
@@ -162,7 +162,7 @@ public sealed class QueueServiceTests : IDisposable
// Only task1 should be running (task2 waiting on the queue slot).
Assert.Single(order);
Assert.Equal(task1.Id, order[0]);
Assert.Equal("1", order[0]);
// Release first task.
gate1.SetResult();
@@ -171,7 +171,7 @@ public sealed class QueueServiceTests : IDisposable
await gate2.Task.WaitAsync(TimeSpan.FromSeconds(5));
Assert.Equal(2, order.Count);
Assert.Equal(task2.Id, order[1]);
Assert.Equal("2", order[1]);
cts.Cancel();
}
@@ -184,7 +184,7 @@ public sealed class QueueServiceTests : IDisposable
var running = new TaskCompletionSource();
var cancelled = false;
var (service, _) = CreateService(async (_, _, _, _, _, ct) =>
var (service, _) = CreateService(async (_, _, _, _, ct) =>
{
running.SetResult();
try
@@ -217,7 +217,7 @@ public sealed class QueueServiceTests : IDisposable
var (listId, _) = await SeedListWithAgentTag();
var tcs = new TaskCompletionSource<RunResult>();
var (service, _) = CreateService((_, _, _, _, _, _) => tcs.Task);
var (service, _) = CreateService((_, _, _, _, _) => tcs.Task);
var task = await SeedQueuedTask(listId);
await service.RunNow(task.Id);
@@ -235,23 +235,23 @@ public sealed class QueueServiceTests : IDisposable
internal sealed class FakeClaudeProcess : IClaudeProcess
{
private readonly Func<string, string, string, string, Func<string, Task>, CancellationToken, Task<RunResult>> _handler;
private readonly Func<string, string, string, Func<string, Task>, CancellationToken, Task<RunResult>> _handler;
private int _callCount;
public int CallCount => _callCount;
public FakeClaudeProcess(
Func<string, string, string, string, Func<string, Task>, CancellationToken, Task<RunResult>>? handler = null)
Func<string, string, string, Func<string, Task>, CancellationToken, Task<RunResult>>? handler = null)
{
_handler = handler ?? ((_, _, _, _, _, _) =>
_handler = handler ?? ((_, _, _, _, _) =>
Task.FromResult(new RunResult { ExitCode = 0, ResultMarkdown = "ok" }));
}
public async Task<RunResult> RunAsync(string prompt, string workingDirectory, string logPath, string taskId,
public async Task<RunResult> RunAsync(string arguments, string prompt, string workingDirectory,
Func<string, Task> onStdoutLine, CancellationToken ct)
{
Interlocked.Increment(ref _callCount);
return await _handler(prompt, workingDirectory, logPath, taskId, onStdoutLine, ct);
return await _handler(prompt, workingDirectory, arguments, onStdoutLine, ct);
}
}