Skip to content

feat(server): wire versioned store and event stream into v2 handler - #1245

Open
mykytanetipa wants to merge 1 commit into
multiserver/cluster-schemasfrom
multiserver/handler-integration
Open

mykytanetipa wants to merge 1 commit into
multiserver/cluster-schemasfrom
multiserver/handler-integration

Conversation

@mykytanetipa

@mykytanetipa mykytanetipa commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Lets DefaultRequestHandlerV2 use the shared store and event stream from #1244, so any replica can serve any request for a remote task. Opt-in and backward compatible: with no event stream and a plain TaskStore, behaviour is exactly as before.

Key changes:

  • New optional event_stream argument; task_store now accepts a plain or a versioned store and is still exposed unchanged as self.task_store.
  • Cancel works from any replica. The cancelling replica records the cancellation in the shared store, and the replica actually running the agent notices on its next save and stops.
  • Resubscribe works from any replica. It returns the current task, then follows the shared event stream from that point on, so the client sees no gap and no duplicates.
  • Warns once if a versioned store is configured without an event stream, since cross-replica streaming stays off until one is supplied.

Tested:

Design discussion: #1224

@mykytanetipa
mykytanetipa added this pull request to stack #1246 September 17, 2026 08:45
@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown

🧪 Code Coverage (vs multiserver/cluster-schemas)

⬇️ Download Full Report

Base PR Delta
src/a2a/server/agent_execution/active_task.py 95.18% 94.18% 🔴 -1.00%
src/a2a/server/agent_execution/active_task_registry.py 97.01% 97.37% 🟢 +0.35%
src/a2a/server/request_handlers/default_request_handler_v2.py 92.53% 87.20% 🔴 -5.34%
src/a2a/server/tasks/task_manager.py 98.68% 98.86% 🟢 +0.18%
Total 93.04% 92.83% 🔴 -0.21%

Generated by coverage-comment.yml

@mykytanetipa
mykytanetipa force-pushed the multiserver/handler-integration branch from c35ee03 to 40da31e Compare September 17, 2026 09:57
@mykytanetipa
mykytanetipa force-pushed the multiserver/handler-integration branch from 40da31e to 9ef150d Compare September 17, 2026 10:36
@mykytanetipa
mykytanetipa marked this pull request as ready for review September 17, 2026 10:51
@mykytanetipa
mykytanetipa requested a review from a team as a code owner September 17, 2026 10:51
@mykytanetipa
mykytanetipa force-pushed the multiserver/handler-integration branch from 9ef150d to d87a6a2 Compare September 22, 2026 22:46
…ndler

Makes DefaultRequestHandlerV2 multi-replica capable while staying fully
backward compatible: with event_stream=None and a plain TaskStore, behaviour is
byte-identical to today.

* Optional `event_stream` constructor param. `task_store` accepts a plain
  TaskStore or a VersionedTaskStore and is exposed unchanged as
  `self.task_store`; internal cluster reads/writes go through a private
  versioned view (the store itself, or a LegacyTaskStoreAdapter for a plain
  one), whose `get` returns a `StoredTask`.
* Version-aware TaskManager (CAS saves, request-boundary cache invalidation).
* ActiveTask/ActiveTaskRegistry publish applied events to the stream when one
  is configured.
* The presence of a shared stream selects the deployment mode. Without one the
  handler is single-process: on_subscribe_to_task serves the resubscription
  from the in-process ActiveTaskRegistry (get_or_create), exactly as before
  cluster support. With a shared stream, on_cancel_task and on_subscribe_to_task
  route across replicas via the shared store and stream (cancel-via-CAS with
  bounded retries; resubscribe tails the stream and serves a store snapshot).
* A VersionedTaskStore configured without an event stream warns once at
  construction: it signals cluster intent, but cross-replica streaming is
  disabled until a shared stream is supplied.

task_manager keeps its cluster imports under TYPE_CHECKING (with lazy
function-level imports for runtime use) so importing a2a.server.cluster first
does not hit an import cycle.

Adds multi-replica behavioural tests (send, resubscribe, cancel, wiring)
sharing one store+stream across two handler instances. The in-memory
VersionedTaskStore and TaskEventStream doubles used by those tests live in the
cluster tests' conftest, since the shipped package provides only interfaces
and database-backed implementations.
@mykytanetipa
mykytanetipa force-pushed the multiserver/handler-integration branch from d87a6a2 to 53bcb60 Compare September 22, 2026 23:20

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant