pub trait AsyncTaskVersioning: Send + Sync {
// Required methods
fn version<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
) -> Pin<Box<dyn Future<Output = Result<u64, A2AError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_versioned<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
history_length: Option<u32>,
) -> Pin<Box<dyn Future<Output = Result<VersionedTask, A2AError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn update_status_checked<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
expected: u64,
state: TaskState,
message: Option<Message>,
) -> Pin<Box<dyn Future<Output = Result<VersionedTask, A2AError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Optimistic-concurrency control over task mutations.
A distinct capability from AsyncTaskLifecycle (hex rule 2 — narrow ports):
a store that needs lost-update protection implements this, while the plain
lifecycle path stays version-free for callers that don’t. The version is a
monotonic counter the store bumps on every successful mutation, including
the unversioned AsyncTaskLifecycle writes — so the two views never drift.
The classic read-modify-write loop:
let VersionedTask { task, version } = store.get_versioned(&id, None).await?;
// … decide the next state from `task` …
let _ = &task;
match store.update_status_checked(&id, version, next_state, msg).await {
Ok(updated) => { /* committed at updated.version */ }
Err(A2AError::VersionConflict { .. }) => { /* re-read and retry */ }
Err(e) => return Err(e),
}Required Methods§
Sourcefn version<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
) -> Pin<Box<dyn Future<Output = Result<u64, A2AError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn version<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
) -> Pin<Box<dyn Future<Output = Result<u64, A2AError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Current stored version of a task. Bumped on every successful mutation.
Sourcefn get_versioned<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
history_length: Option<u32>,
) -> Pin<Box<dyn Future<Output = Result<VersionedTask, A2AError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_versioned<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
history_length: Option<u32>,
) -> Pin<Box<dyn Future<Output = Result<VersionedTask, A2AError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch a task together with its current version (history-limited as in
AsyncTaskLifecycle::get).
Sourcefn update_status_checked<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
expected: u64,
state: TaskState,
message: Option<Message>,
) -> Pin<Box<dyn Future<Output = Result<VersionedTask, A2AError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update_status_checked<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 TaskId,
expected: u64,
state: TaskState,
message: Option<Message>,
) -> Pin<Box<dyn Future<Output = Result<VersionedTask, A2AError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Update status only if the stored version equals expected.
On success returns the mutated task and its newly bumped version. If the
stored version has advanced past expected, fails with
A2AError::VersionConflict and leaves the task untouched.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".