a2aproject / a2aproject/a2a-dotnet

Task live coordination is process-local across server instances

未关闭
#463 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
C#
星标
262
派生
64
平均合并
5 天 2 小时
30 天内合并 PR
31

描述

## Summary

Task persistence can be shared across server instances, but two live coordination paths in `A2AServer` are process-local:

- `SubscribeToTask` uses `ChannelEventNotifier` subscriber channels.
- `CancelTask` looks up the running task in `_backgroundCancellations`, an in-process dictionary of `CancellationTokenSource` instances.

Consequently, a request routed to a different process/pod can read and mutate the durable task while failing to notify the subscriber or interrupt the process that is executing the task.

This is not a task snapshot persistence issue. `GetTask` may return the correct durable state while live delivery or execution interruption has not occurred.

## Current behavior

### Subscribe across instances

From [`ChannelEventNotifier`](https://github.com/a2aproject/a2a-dotnet/blob/87fd44843dd16339cdb59c2ff547fe374ac46736/src/A2A/Server/ChannelEventNotifier.cs), subscribers and per-task locks are stored in process memory.

1. Pod B accepts `SubscribeToTask` and creates a local subscriber channel.
2. Pod A applies and persists a later task event.
3. Pod A notifies only subscribers registered in Pod A.
4. The subscriber on Pod B can miss the live event even though `GetTask` later returns the updated snapshot.

### Cancel across instances

In [`A2AServer.CancelTaskAsync`](https://github.com/a2aproject/a2a-dotnet/blob/fdf22d790cc3c80a157311c41d2ec0cd71815173/src/A2A/Server/A2AServer.cs#L822-L863), background execution cancellation uses `_backgroundCancellations.TryRemove(request.Id, ...)`.

1. Pod A owns a return-immediately background execution and its local cancellation token.
2. Pod B accepts `CancelTask` for the same durably stored task.
3. Pod B has no matching entry in its `_backgroundCancellations` dictionary.
4. The task may be projected or persisted as canceled by the handler/store while the actual work on Pod A continues consuming resources.

Application-level fencing can reject stale terminal writes, but it does not stop the running work.

## Expected behavior

For multi-instance deployments, the SDK should expose an explicit live-coordination extension point or clearly document that the default implementation requires routing affinity/single-instance hosting.

A robust application-provided implementation should be able to use:

- durable task state/events as the authority;
- a distributed notifier/backplane as a low-latency wake-up hint;
- durable replay or polling as a fallback for lost notifications;
- separate notification semantics for subscriber wake-up and execution cancellation.

The notifier must not become the source of truth, and duplicate, delayed, reordered, or lost notifications must be safe.

## Possible SDK directions

- Document that `ChannelEventNotifier` and `_backgroundCancellations` are process-local.
- Expose injectable abstractions for subscription notification and active-execution cancellation/routing while retaining the current in-memory defaults.
- Keep persistence (`ITaskStore`) separate from notification, but document how a distributed store and distributed coordination provider compose.
- Add deterministic two-server tests demonstrating the default limitation and validating custom distributed implementations.

## Minimal repros

### Subscribe

1. Register a subscriber for `taskId` on notifier/server A.
2. Apply or notify an event on notifier/server B.
3. Observe that A's subscriber does not receive it.
4. Repeat with one notifier and observe successful delivery.

### Cancel

1. Start return-immediately work for `taskId` on server A.
2. Share the task snapshot through a common `ITaskStore`.
3. Call `CancelTaskAsync` on server B.
4. Observe that server A's cancellation token is not canceled.
5. Repeat on server A and observe that local cancellation succeeds.

## Why this matters

A service can pass single-process tests and expose correct durable snapshots while still hanging subscriptions or continuing canceled work under load-balanced production routing. The topology limitation should be explicit, and applications need supported extension seams to provide cross-instance coordination.

贡献指南

打开贡献指南

调研方向

The issue is in A2AServer.cs and ChannelEventNotifier.cs. Start by reading the linked code sections to understand the process-local dictionaries. Look at ITaskStore for persistence. The work involves designing a distributed coordination mechanism, which requires deep knowledge of the SDK's architecture and distributed systems concepts. 'Done' means the SDK either documents the limitation or provides extension points, validated by the described multi-server tests.

由索引模型根据 Issue 内容生成。

评估

技术栈
csharp, docker, kubernetes
领域
backend, distributed-systems
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
活跃
描述清晰度
描述清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。