Repository navigation
fix(server): warn when queue_manager is ignored in DefaultRequestHandlerV2 - #1153
mykytanetipa merged 3 commits into
Conversation
…lerV2 DefaultRequestHandlerV2 accepts a queue_manager for signature compatibility but never stores or uses it — v2 delegates event streaming to an in-memory ActiveTaskRegistry, so a custom or distributed QueueManager (e.g. Redis for multi-replica reconnection) is silently dropped. Emit a warning at construction so the misconfiguration is visible, pointing at the LegacyRequestHandler / task-affinity workarounds. Fixes a2aproject#1135
|
Confirmed the root cause on current main: DefaultRequestHandlerV2 still accepts queue_manager in its signature (84) but never stores or uses it, since V2 drives streaming through ActiveTaskRegistry (108). A caller passing a Redis-backed QueueManager gets it dropped with no signal, which is the exact failure in the issue. Warning on a non-None value is a reasonable stopgap given that actually honoring a distributed manager in V2 is an architectural change, and it does satisfy the issue's stated bar (either the parameter works, or passing one warns). One suggestion to make the warning land where it matters. logger.warning surfaces in server logs, but the point of the issue is that this is easy to miss, especially across replicas. warnings.warn(..., DeprecationWarning, stacklevel=2) would put the signal at the caller's construction site, make it catchable and filterable in test suites, and read as a deprecation of the parameter rather than a runtime log line. Emitting both (the DeprecationWarning plus the existing log) would cover interactive and headless callers. Since the parameter is being kept only for backward compatibility, stating that deprecation in the docstring would also carry it into the generated API docs. Tests and CI are green. This is a clean interim fix; the warnings.warn form would match the issue's raises-or-warns framing a little more faithfully. |
Adds warnings.warn(..., DeprecationWarning, stacklevel=2) alongside the existing logger.warning so the signal lands at the caller's construction site and is catchable in test suites. Documents the ignored parameter on the class docstring. Matches the existing convention in a2a/server/events/event_queue.py.
There was a problem hiding this comment.
LGTM
Confirm that queue_manager should remain as a no-op param on DefaultRequestHandlerV2 for handler schema compatibility, the logging implementation is correct and satisfies #1135.
Actual multi-replica streaming support for DefaultRequestHandlerV2 is a separate architectural effort for the maintainer team.
🤖 I have created a release *beep* *boop* --- ## [1.1.4](v1.1.3...v1.1.4) (2026-09-07) ### Features * **itk:** register itk-python-v10-agent as a uv workspace member and update dependency version markers ([#1203](#1203)) ([6eee895](6eee895)) * **itk:** use shared scenarios ([#1201](#1201)) ([b4a0b21](b4a0b21)) ### Bug Fixes * make event queue sink removal idempotent ([#1134](#1134)) ([58c72c6](58c72c6)) * omit artifacts from list tasks responses ([#1212](#1212)) ([35ef52e](35ef52e)) * owner-scope cancel/subscribe and write terminal state on cancel ([#1159](#1159), [#1170](#1170)) ([#1172](#1172)) ([ddbf853](ddbf853)) * prevent first-owner write loss in in-memory stores ([#1194](#1194)) ([bcc489c](bcc489c)) * **server:** let subscriber taps evict on full instead of wedging dispatch ([#1137](#1137)) ([0c2126f](0c2126f)) * **server:** surface producer errors after failed tasks ([#1229](#1229)) ([bc32d7e](bc32d7e)) * **server:** validate push-notification URLs at config creation ([#1173](#1173)) ([3eb88e2](3eb88e2)) * **server:** validate push-notification URLs before dispatch (SSRF hardening) ([#1164](#1164)) ([57a9df3](57a9df3)) * **server:** warn when queue_manager is ignored in DefaultRequestHandlerV2 ([#1153](#1153)) ([08fd223](08fd223)) ### Documentation * **server:** say what the evict-on-full check actually tests ([#1209](#1209)) ([4b7b242](4b7b242)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).

Summary
Fixes #1135.
DefaultRequestHandlerV2.__init__accepts aqueue_managerargument (kept for signature compatibility withDefaultRequestHandler) but never stores or uses it. As @rohityan confirmed on the issue, v2 delegates event streaming to an in-memoryActiveTaskRegistry, so any custom or distributedQueueManager— e.g. a Redis-backed one used for multi-replica stream reconnection — is silently dropped. After upgrading, multi-replica streaming breaks with no error or warning.Fix
Emit a
logger.warningat construction when a non-Nonequeue_manageris passed, explaining that it is ignored in v2 and pointing at the documented workarounds (switch toLegacyRequestHandler, or route/tasks/{id}:subscribeto the replica holding theActiveTask). This turns a silent misconfiguration into a visible one without changing v2's architecture. Also corrected the now-inaccurate inline comment on the parameter.Evidence
default_request_handler_v2.py__init__bindsagent_executor/task_store/etc. but has noself._queue_manager = queue_manager(contrastdefault_request_handler.py:123, which does store it and uses it at lines 209/313/503/611).self._active_task_registry = ActiveTaskRegistry(...).Testing
Added two tests to
tests/server/request_handlers/test_default_request_handler_v2.py:test_init_warns_when_queue_manager_passed— asserts a WARNING mentioningqueue_manageris logged (fails onmain, passes with the fix).test_init_no_warning_without_queue_manager— asserts no such warning in the default case.ruff check,ruff format --check, andty checkall clean on the changed files.This change was developed with AI assistance; I verified the root cause and behavior against the code paths cited above, reviewed every line, and ran the tests.