Skip to content

fix: avoid unread main queue copies in default in-memory manager (0.3.x) - #1256

Closed
Evader-lgb wants to merge 3 commits into
a2aproject:0.3.xfrom
Evader-lgb:codex/03x-inmemory-queue-fanout
Closed

Evader-lgb wants to merge 3 commits into
a2aproject:0.3.xfrom
Evader-lgb:codex/03x-inmemory-queue-fanout

Conversation

@Evader-lgb

Copy link
Copy Markdown

Description

The default InMemoryQueueManager in the legacy 0.3.x line always returns a ChildQueue from createOrTap(). MainQueue nevertheless retains a second copy of every event and acquires a separate semaphore permit. Consuming all child events does not release those permits, so event 1001 blocks with the default capacity even with fast consumers. Increasing the main capacity only moves the failure boundary.

This is a maintenance-branch fix for the behavior reproduced with 0.3.3.Final. It is not a claim about the newer main-branch event-bus implementation or the root cause of every production SSE timeout.

Change

Add a package-private dispatch-only builder mode and enable it only in InMemoryQueueManager's default factory. In this mode, MainQueue distributes events to children and invokes its hook without retaining an unused main copy or acquiring a permit for that copy. Child queues still enforce bounded backpressure.

No bookkeeping dequeue is performed, so enqueue does not falsely signal awaitQueuePollerStart(). Existing close callbacks and task-state handling remain in use. Directly built queues, explicitly added queues, custom factories, and the replicated queue manager's custom factory retain their previous behavior.

The class Javadoc documents that default-manager consumers use the returned child and that tap does not replay history. With no subscribers, the default dispatch-only main queue retains no events; later subscribers receive future events.

Tests

Five queue-only regression tests cover:

  • 10000 events delivered in order to two subscribers without reading MainQueue;
  • enqueue alone does not signal polling start, while a real child dequeue does;
  • a slow subscriber still blocks production until it consumes;
  • an active task can resubscribe after a period without subscribers, and final close removes its queue;
  • direct queues and custom factories still retain main-queue events.

Validation:

  • Unmodified 0.3.3.Final fails the 10000-event regression with a timeout in semaphore acquisition.
  • On this 0.3.x branch: mvn -B -ntp -pl server-common -am test — BUILD SUCCESS, 411 tests, 0 failures, 0 errors, 0 skipped (265 in server-common).
  • Queue-focused run: 40 tests, 0 failures/errors/skips.
  • git diff --check passes.
  • Java 21 runtime, project compiler release 17. The isolated 0.3.3 comparison used cached Jackson 2.17.2; the repository run used its unmodified dependency configuration.

Related: agentscope-ai/agentscope-java#2507.
Supersedes the application-level workaround proposed in agentscope-ai/agentscope-java#3941, whose enqueue-hook dequeue triggered polling-start signals prematurely. AgentScope 2.0.x would still require a released SDK fix; this PR alone does not change its published dependency.

  • Follow the CONTRIBUTING guide.
  • Conventional commit title.
  • Relevant module and dependency-module tests pass.
  • Updated consumption/lifecycle documentation in the class Javadoc.

@Evader-lgb

Evader-lgb commented Nov 2, 2026 •

Copy link
Copy Markdown
Author

CI status note: the local server-common reactor test command in the description passed, but the GitHub checks are not all green.

  • The TCK Java 21 job failed while installing Python dependencies, before starting the Java SUT. Its log reports: "the configured Python version (3.15) is newer than PyO3's maximum supported version (3.14)" (cachebox via deepdiff). The other TCK matrix jobs were cancelled.
  • The Java 21 build job passed the server-common tests, including all five new regression tests. It later failed in KafkaReplicationIntegrationTest and MultiInstanceReplicationTest during container setup, reporting that a valid Docker environment could not be found. The stack traces fail in Testcontainers DockerClientProviderStrategy before those integration tests exercise event delivery.

I have not changed the workflows or treated setup failures as passing integration/TCK results. Review of the maintenance-branch fix and a completed CI run are still needed. Related issue evidence is posted at agentscope-ai/agentscope-java#2507; the application-level workaround agentscope-ai/agentscope-java#3941 has been withdrawn.

@kabir

kabir commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

I'm trying to rerun them. Sometimes GH Actions plays up

@kabir

kabir commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Ah, I see this targets 0.3.x. I'm not sure if our CI still works with that any longer.

Is there a reason you cannot use 1.x? We have a 0.3 protocol compatibility layer there, and this is where the development goes on these days

@Evader-lgb

Copy link
Copy Markdown
Author

Thanks for taking a look and rerunning the checks! I’ll keep an eye on the results and follow up if any changes are needed.

@Evader-lgb

Copy link
Copy Markdown
Author

Thanks for pointing out the 1.x compatibility layer! The reason I targeted 0.3.x is that AgentScope Java's 2.0.x maintenance branch currently depends on A2A Java SDK 0.3.3.Final (BOM), and we reproduced the queue issue against that version. I was exploring a fix for users still on that dependency line, as discussed in agentscope-ai/agentscope-java#2507.

I also see that AgentScope Java's main branch now uses A2A Java SDK 1.4.0.Final. We haven't yet evaluated migrating our existing deployment to that line or validated the 0.3 compatibility layer in our setup, so I can't say that upgrading is impossible. The protocol compatibility layer is helpful information for us to investigate.

Given that active development is focused on 1.x, would a 0.3.x maintenance fix like this still be considered, or would you recommend focusing on migration to 1.x instead? Thanks!

@kabir

kabir commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Preferably we would just do 1.x now since it is the active branch.

But if you absolutely must have another 0.3.x release, we can accommodate that. But I'd need some help with the CI jobs.
Probably we'd need to adjust https://github.com/a2aproject/a2a-java/tree/0.3.x/.github/workflows to only trigger on the 0.3.x branch

And maybe something in https://github.com/a2aproject/a2a-java/tree/main/.github/workflows to make them not trigger for 0.3.x. If that is possible. If not we'd need to narrow these to main, although I would like to avoid this.

Sorry for the rushed reply, I am on my own this week and next :-)

@Evader-lgb

Copy link
Copy Markdown
Author

Thanks for clarifying. I understand that 1.x is the active line and your preference is to focus development there.

The reason I am asking about a 0.3.x backport is that we have users running AgentScope Java 2.0.x with a2a-java-sdk-server-common:0.3.3.Final. Moving those users to the 1.x SDK path is not an immediate option for us, so a fix in the 0.3.x line would address a dependency path that is still in use. The latest 2.0.x stable release I found is AgentScope Java 2.0.4, released on October 8, and it still uses the 0.3.3.Final SDK.

I tested the published 1.4.0.Final artifact locally with the default InMemoryQueueManager and MainEventBusProcessor. The single-subscriber and two-subscriber queue-only reproductions both delivered 5,001 status events per subscriber without consuming the main queue or blocking the producer. This suggests the specific capacity-exhaustion issue is not reproducible on the default 1.4.0.Final path, but it does not provide a fix for users who remain on 0.3.3.Final.

I understand this would require a new 0.3.x patch release; the already-published 0.3.3.Final would not change. I am willing to help make the 0.3.x workflow triggers branch-specific if a backport is still acceptable. Would you be open to proceeding with the 0.3.x fix and release?

@kabir

kabir commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Hi, yes we can do it once we get CI working. You might have to do a few rounds testing it in your own repository, to make sure things trigger. Once that is done, please open a PR with the CI fixes, and then we can look at merging this one?

@Evader-lgb

Copy link
Copy Markdown
Author

Thanks @kabir! Before starting, I went and checked the workflow definitions on both branches — I think the scope is narrower than we assumed:

  • main needs no changes: GitHub evaluates workflow files from the ref the event happened on, so main's workflows can never fire for 0.3.x pushes/PRs (and its release-please is already main-filtered; the maven-central publish is tag-triggered).
  • On 0.3.x, the one real gap is release-please.yml, hardcoded to trigger on main only — so the automated release path is dead on 0.3.x. Everything else either already runs unfiltered or is tag-triggered.

So the CI PR would target 0.3.x only: add branches: [0.3.x] filters to the push/PR workflows there, and retarget release-please.yml to 0.3.x (trigger + target-branch: 0.3.x).

Two things I can't tell from the repo:

  1. My default plan is to wire release-please to 0.3.x (trigger + target-branch) so the release is automated — but if you'd rather just cut the tag manually, I'll leave release-please.yml alone and the CI PR gets even smaller.
  2. If those env-dependent failures on fix: avoid unread main queue copies in default in-memory manager (0.3.x) #1256 (TCK Python 3.15/PyO3, Kafka/Docker) are required checks for merging into 0.3.x, I'll pin the Python version and skip the Docker-dependent profile in the same CI PR.

Either way I'll start validating the triggers in my fork and report back.

@kabir

kabir commented Nov 2, 2026

Copy link
Copy Markdown
Collaborator

Don't worry about release-please, it is just noise from whoever set up the repository for us. We broke it right away :-)

We use https://github.com/a2aproject/a2a-java/blob/0.3.x/.github/workflows/release-to-maven-central.yml to deploy when a tag is made. It works fine on main for the 1.x releases, but I'm not sure if it will work or not with 0.3.x. In the worst case I will just deploy the release manually.

The main things to have working are the two currently failing workflows:
https://github.com/a2aproject/a2a-java/blob/0.3.x/.github/workflows/build-and-test.yml
https://github.com/a2aproject/a2a-java/blob/0.3.x/.github/workflows/run-tck.yml

@Evader-lgb

Copy link
Copy Markdown
Author

Quick follow-up: I've opened a separate PR with the CI fixes we discussed — #1274 (scope the 0.3.x workflow triggers to the branch, pin the TCK Python to 3.13, and skip the docker-dependent replication tests in build-and-test). All four workflows pass on 0.3.x-targeted runs in my fork; the verification trail is linked in that PR.

Once it lands I'll rebase this PR so its checks run green — it should then be ready for your review.

@kabir

kabir commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

Hi @Evader-lgb I merged your CI one. Can you rebase your branch on upstream 0.3.x?

I tried doing it here, and normally have rights to push to PR forks, but in this case it didn't work.
I opened a draft PR here #1276 which does it

@kabir

kabir commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

Actually, I'll use my PR so I'm closing this one.
Here is the new PR #1276

@Evader-lgb

Copy link
Copy Markdown
Author

Thanks for rebasing and merging the fix! Appreciate your help.

@kabir

kabir commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

The release is here https://github.com/a2aproject/a2a-java/releases/tag/v0.3.4.Final. I've deployed to Maven, so it should hopefully show up soon. Sometimes it takes a few minutes, others a few hours :-)

@kabir kabir closed this Nov 3, 2026
@kabir

kabir commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

The release is published. https://repo1.maven.org/maven2/io/github/a2asdk/a2a-java-sdk-parent/0.3.4/

I messed up a bit by omitting the '.Final' suffix we've used in previous releases, but don't want to rerelease at this stage :-)

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.

2 participants