Skip to main content

AsyncTaskVersioning

Trait AsyncTaskVersioning 

Source
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§

Source

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.

Source

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).

Source

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".

Implementors§