Class InMemoryTaskStore
- All Implemented Interfaces:
TaskStateProvider,TaskStore
TaskStore and TaskStateProvider.
This implementation uses a ConcurrentHashMap to store tasks in memory.
Tasks are lost on application restart. For persistent storage, use a database-backed
implementation such as the JPA TaskStore in the extras module.
This is the default TaskStore used when no other implementation is provided.
Exception Behavior
InMemoryTaskStore has minimal exception scenarios compared to database-backed implementations:- No TaskSerializationException: Task objects are stored directly in memory without serialization. No JSON parsing or schema compatibility issues can occur.
- No TaskPersistenceException: ConcurrentHashMap operations do not involve I/O, network, or transactional concerns. Standard put/get/remove operations are guaranteed to succeed under normal JVM operation.
- OutOfMemoryError (potential): The only failure scenario is JVM heap exhaustion if
too many tasks are stored. This is an
Error(not Exception) and indicates a fatal system condition requiring JVM restart and capacity planning.
Design Rationale
This implementation intentionally does NOT throwTaskStoreException or its subclasses
because:
- No serialization step exists - tasks stored as Java objects
- No I/O or network operations that can fail
- ConcurrentHashMap guarantees thread-safe operations without checked exceptions
- Memory exhaustion (OutOfMemoryError) is an unrecoverable system failure
Comparison to Database Implementations
Database-backed implementations (e.g., JpaDatabaseTaskStore) throw exceptions for:- Serialization errors (JSON parsing, schema mismatches)
- Connection failures (network, timeouts)
- Transaction failures (deadlocks, constraint violations)
- Capacity issues (disk full, quota exceeded)
Memory Management Considerations
Callers should monitor memory usage and implement task cleanup policies:
// Example: Delete finalized tasks older than 48 hours
ListTasksParams params = new ListTasksParams.Builder()
.statusTimestampBefore(Instant.now().minus(Duration.ofHours(48)))
.build();
List<Task> oldTasks = taskStore.list(params, context).tasks();
oldTasks.stream()
.filter(task -> task.status().state().isFinal())
.forEach(task -> taskStore.delete(task.id()));
Thread Safety
All operations are thread-safe viaConcurrentHashMap. Multiple threads can
concurrently save, get, list, and delete tasks without synchronization. Last-write-wins
semantics apply for concurrent save() calls to the same task ID.-
Constructor Summary
ConstructorsConstructorDescriptionInMemoryTaskStore(@Nullable TaskAuthorizationProvider authorizationProvider) Creates an in-memory task store with optional task-level authorization.InMemoryTaskStore(jakarta.enterprise.inject.Instance<TaskAuthorizationProvider> authorizationProviderInstance) -
Method Summary
Modifier and TypeMethodDescriptionvoidDeletes a task by its ID.@Nullable org.a2aproject.sdk.spec.TaskRetrieves a task by its ID.booleanisTaskActive(String taskId) Determines whether a task is considered active for queue management purposes.booleanisTaskFinalized(String taskId) Determines whether a task is in a final state, ignoring the grace period.org.a2aproject.sdk.jsonrpc.common.wrappers.ListTasksResultlist(org.a2aproject.sdk.spec.ListTasksParams params, @Nullable ServerCallContext context) List tasks with optional filtering and pagination.voidsave(org.a2aproject.sdk.spec.Task task, boolean isReplicated) Saves or updates a task.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.a2aproject.sdk.server.tasks.TaskStore
isReadAuthorized
-
Constructor Details
-
InMemoryTaskStore
public InMemoryTaskStore() -
InMemoryTaskStore
@Inject public InMemoryTaskStore(@Any jakarta.enterprise.inject.Instance<TaskAuthorizationProvider> authorizationProviderInstance) -
InMemoryTaskStore
Creates an in-memory task store with optional task-level authorization.This constructor supports programmatic wiring in non-CDI runtimes such as Spring Framework.
- Parameters:
authorizationProvider- provider used to filter tasks during list operations;nullpermits all tasks
-
-
Method Details
-
save
public void save(org.a2aproject.sdk.spec.Task task, boolean isReplicated) Description copied from interface:TaskStoreSaves or updates a task. -
get
Description copied from interface:TaskStoreRetrieves a task by its ID. -
delete
Description copied from interface:TaskStoreDeletes a task by its ID. -
list
public org.a2aproject.sdk.jsonrpc.common.wrappers.ListTasksResult list(org.a2aproject.sdk.spec.ListTasksParams params, @Nullable ServerCallContext context) Description copied from interface:TaskStoreList tasks with optional filtering and pagination.Authorization filtering: When a
TaskAuthorizationProviderbean is present, implementations must callcheckReadfor each candidate task and exclude tasks for which the check returnsfalse. The filtering should be applied before pagination so that page sizes are correct from the caller's perspective. If no provider is present, all tasks are returned.⚠ Custom implementation warning: Returning unfiltered results bypasses the authorization model and can leak tasks belonging to other users. Custom implementations must apply per-task
checkReadfiltering before pagination. TheTaskAuthorizationProvidershould be declared as a CDI dependency and injected via the constructor or@Inject. -
isTaskActive
Description copied from interface:TaskStateProviderDetermines whether a task is considered active for queue management purposes.This method includes the grace period in its check. A task is considered active if:
- Its state is not final, OR
- Its state is final but finalized within the grace period (now < finalizedAt + gracePeriod)
This method is used to decide whether to process late-arriving events.
- Specified by:
isTaskActivein interfaceTaskStateProvider- Parameters:
taskId- the ID of the task to check- Returns:
trueif the task is active (or recently finalized within grace period),falseotherwise
-
isTaskFinalized
Description copied from interface:TaskStateProviderDetermines whether a task is in a final state, ignoring the grace period.This method performs an immediate check: returns
trueonly if the task is in a final state (COMPLETED, CANCELED, FAILED, etc.), regardless of when it was finalized.This method is used by cleanup callbacks and MainQueue closing logic to decide whether a queue can be closed and removed. By ignoring the grace period, it ensures responsive cleanup while late in-flight events are still handled by the grace period mechanism for
isTaskActive.- Specified by:
isTaskFinalizedin interfaceTaskStateProvider- Parameters:
taskId- the ID of the task to check- Returns:
trueif the task is in a final state (ignoring grace period),falseotherwise
-