fix(a2a-client): stopped registry starts no watch loops

This commit is contained in:
EugeneTes
2026-10-08 14:15:05 +00:00
parent ab714a24ce
commit adee225fcb
3 changed files with 47 additions and 1 deletions

View File

@@ -462,6 +462,29 @@ public sealed class A2AWatchTests : IDisposable
Assert.Single(PendingFile.Read(_ws));
}
[Fact]
public async Task Start_AfterStop_KeepsTheRecordButStartsNoLoop()
{
await using var remote = await RemoteAgentServer.StartAsync();
remote.Faux.Enqueue(FauxTurn.Say("Later"));
WriteAgents();
var delivery = new RecordingDelivery(_ws);
await using var registry = new A2AWatchRegistry(TimeProvider.System, remote.Handler) { SourceOverride = WatchSources.Poll, PollDelays = [TimeSpan.FromMilliseconds(50)] };
registry.UseDelivery(delivery);
var settings = new A2AClientSettings();
using var agent = await registry.Connector(settings).ConnectAsync(AgentsFile.Find(_ws, "remote")!, CancellationToken.None);
var task = await StartRemoteTaskAsync(agent);
await registry.StopAsync(); // shutting down while a tool call hands a task over
var record = await registry.StartAsync("1", _ws, agent, task, settings, CancellationToken.None);
await registry.RearmAsync(_ws, record with { WatchId = "w2", TaskId = "other" }, settings);
Assert.Empty(registry.List("1"));
Assert.Equal(2, PendingFile.Read(_ws).Count); // restored on the next start
Assert.Equal(0, await registry.RestoreAsync(settings, CancellationToken.None));
Assert.Empty(registry.List("1"));
await Task.Delay(500);
Assert.Empty(delivery.Delivered);
}
[Fact]
public async Task StopWatching_RacingFinish_DoesNotResurrectTheRecord()
{

View File

@@ -106,8 +106,9 @@ public sealed class A2AClientHost : IAsyncDisposable
public async ValueTask DisposeAsync()
{
await Registry.DisposeAsync();
// Sessions first: a delivery or session-start flush in flight finishes against a live registry.
foreach (var session in _sessions) await session.DisposeAsync();
await Registry.DisposeAsync();
await _services.DisposeAsync();
try { Directory.Delete(_root, true); } catch (IOException) { } catch (UnauthorizedAccessException) { }
}