-
Notifications
You must be signed in to change notification settings - Fork 156
feat: Implement robust replication and task-aware queue lifecycle #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat(server): Implement robust replication and task-aware queue lifec…
…ycle
This commit introduces a comprehensive overhaul of the event replication and queue lifecycle management system. It ensures data consistency for all request types, enhances robustness in distributed environments,
and adds support for new operational patterns.
Previously, the system suffered from several issues: blocking requests could lead to data loss, the replication mechanism was susceptible to race conditions, and the queue lifecycle was not fully aligned with the
task's state, preventing patterns like fire-and-forget.
This change implements three major architectural improvements:
1. Fix Data Loss in Blocking Requests:
* Corrects a critical bug where blocking onMessageSend calls would stop processing events after returning the first one.
* The ResultAggregator now ensures all subsequent events from the agent are consumed in the background, guaranteeing the final task state is correctly persisted in the TaskStore.
2. Authoritative State & Transaction-Aware Replication:
* Introduces a TaskStateProvider interface to decouple queue management from the persistence layer, allowing the ReplicatedQueueManager to check the authoritative state of a task from a shared database.
* Replaces time-based cleanup delays with a robust, transaction-aware "poison pill" (QueueClosedEvent). This event is now broadcast via a CDI observer only after the final task state is successfully committed
to the database, eliminating race conditions in distributed cleanup.
3. Task-Aware Queue Lifecycle & `ThreadLocal` Removal:
* Refactors the EventQueue to use a polymorphic EventQueueItem, which cleanly distinguishes between local and replicated events. This allows for the complete removal of the isHandlingReplicatedEvent
ThreadLocal, simplifying the concurrency model.
* The MainQueue lifecycle is now strictly tied to the task's finalization state. As a core guarantee, a `MainQueue` will remain open for a task as long as the task is not in a final state. This holds true even
if all consumers disconnect, enabling reliable fire-and-forget operations and late resubscriptions, while queues for finalized tasks are correctly garbage collected.- Loading branch information
commit eb87d9c08b1428548f92d7b6d6d7573fd189a5c2
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,3 +47,4 @@ nbproject/ | |
|
|
||
| # Private Claude config | ||
| .claude/ | ||
| .serena/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <groupId>io.github.a2asdk</groupId> | ||
| <artifactId>a2a-java-sdk-parent</artifactId> | ||
| <version>0.3.0.Beta3-SNAPSHOT</version> | ||
| <relativePath>../../pom.xml</relativePath> | ||
| </parent> | ||
|
|
||
| <artifactId>a2a-java-extras-common</artifactId> | ||
| <name>A2A Java SDK :: Extras :: Common</name> | ||
| <description>Common classes shared across extras modules</description> | ||
|
|
||
| <dependencies> | ||
| <!-- Minimal dependencies - just what's needed for event classes --> | ||
| </dependencies> | ||
| </project> |
26 changes: 26 additions & 0 deletions
26
extras/common/src/main/java/io/a2a/extras/common/events/TaskFinalizedEvent.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| package io.a2a.extras.common.events; | ||
|
|
||
| /** | ||
| * CDI event fired when a task reaches a final state and is successfully persisted to the database. | ||
| * This event is fired AFTER the database transaction commits, making it safe for downstream | ||
| * components to assume the task is durably stored. | ||
| * | ||
| * <p>Used by the replicated queue manager to send poison pill events after ensuring | ||
| * the final task state is committed to the database, eliminating race conditions. | ||
| */ | ||
| public class TaskFinalizedEvent { | ||
| private final String taskId; | ||
|
|
||
| public TaskFinalizedEvent(String taskId) { | ||
| this.taskId = taskId; | ||
| } | ||
|
|
||
| public String getTaskId() { | ||
| return taskId; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return "TaskFinalizedEvent{taskId='" + taskId + "'}"; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.