pub struct SqliteTaskStore { /* private fields */ }Expand description
SQLite-backed TaskStore.
Stores tasks as JSON blobs in a tasks table. Suitable for single-node
production deployments that need persistence across restarts.
§Schema
The store auto-creates the following table on first use:
CREATE TABLE IF NOT EXISTS tasks (
id TEXT PRIMARY KEY,
context_id TEXT NOT NULL,
state TEXT NOT NULL,
data TEXT NOT NULL,
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%d %H:%M:%f','now'))
);list() returns tasks most-recently-updated first (spec §3.1.4), ordered by
(updated_at DESC, id DESC) with a composite row-value cursor. updated_at
is written at millisecond precision in a fixed-width format so TEXT
comparison matches chronological order.
Implementations§
Source§impl SqliteTaskStore
impl SqliteTaskStore
Sourcepub async fn new(url: &str) -> Result<Self, Error>
pub async fn new(url: &str) -> Result<Self, Error>
Opens (or creates) a SQLite database and initializes the schema.
§Errors
Returns an error if the database cannot be opened or the schema migration fails.
Sourcepub async fn with_migrations(url: &str) -> Result<Self, Error>
pub async fn with_migrations(url: &str) -> Result<Self, Error>
Opens a SQLite database with automatic schema migration.
Runs all pending migrations before returning the store. This is the recommended constructor for production deployments because it ensures the schema is always up to date without duplicating DDL statements.
§Errors
Returns an error if the database cannot be opened or any migration fails.
Trait Implementations§
Source§impl Clone for SqliteTaskStore
impl Clone for SqliteTaskStore
Source§fn clone(&self) -> SqliteTaskStore
fn clone(&self) -> SqliteTaskStore
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SqliteTaskStore
impl Debug for SqliteTaskStore
Source§impl TaskStore for SqliteTaskStore
impl TaskStore for SqliteTaskStore
Source§fn save_artifact_delta<'a>(
&'a self,
task: &'a Task,
delta: ArtifactDelta,
) -> Pin<Box<dyn Future<Output = A2aResult<()>> + Send + 'a>>
fn save_artifact_delta<'a>( &'a self, task: &'a Task, delta: ArtifactDelta, ) -> Pin<Box<dyn Future<Output = A2aResult<()>> + Send + 'a>>
Appends into the stored JSON document instead of rewriting it.
save serializes the whole task in Rust and ships it as a bind
parameter, so a streaming agent pays for every artifact it has already
persisted on every subsequent event. This sends only what changed and
lets SQLite splice it into the document with json_set.
§What this does and does not remove
Removed: the Rust-side serde_json::to_string of the whole task, and
the transfer of the whole document as a parameter. Both scale with the
stream so far.
Not removed: SQLite still parses and rewrites the row internally, so
the statement remains linear in document size. A blob-per-task schema
cannot avoid that; only a normalized artifacts table could, and the
measurement in benches/benches/backpressure.rs says that is not where
this store’s time goes — the per-event round trip dominates by roughly
3:1 at 502 events. Doing the larger surgery for the smaller term would
be the wrong trade, and it is recorded here rather than left implied.
updated_at is deliberately untouched: it carries the status
timestamp that orders list (§3.1.4), and appending an artifact does
not change a task’s status. This matches InMemoryTaskStore, which
keeps the task’s list position across an append.
Falls back to save whenever the delta cannot be applied exactly.
The refused cases, and why each one is refused, are documented on the
private statement builder this calls.
Source§fn save<'a>(
&'a self,
task: &'a Task,
) -> Pin<Box<dyn Future<Output = A2aResult<()>> + Send + 'a>>
fn save<'a>( &'a self, task: &'a Task, ) -> Pin<Box<dyn Future<Output = A2aResult<()>> + Send + 'a>>
Source§fn get<'a>(
&'a self,
id: &'a TaskId,
) -> Pin<Box<dyn Future<Output = A2aResult<Option<Task>>> + Send + 'a>>
fn get<'a>( &'a self, id: &'a TaskId, ) -> Pin<Box<dyn Future<Output = A2aResult<Option<Task>>> + Send + 'a>>
None if not found. Read moreSource§fn list<'a>(
&'a self,
params: &'a ListTasksParams,
) -> Pin<Box<dyn Future<Output = A2aResult<TaskListResponse>> + Send + 'a>>
fn list<'a>( &'a self, params: &'a ListTasksParams, ) -> Pin<Box<dyn Future<Output = A2aResult<TaskListResponse>> + Send + 'a>>
Source§fn insert_if_absent<'a>(
&'a self,
task: &'a Task,
) -> Pin<Box<dyn Future<Output = A2aResult<bool>> + Send + 'a>>
fn insert_if_absent<'a>( &'a self, task: &'a Task, ) -> Pin<Box<dyn Future<Output = A2aResult<bool>> + Send + 'a>>
Auto Trait Implementations§
impl !RefUnwindSafe for SqliteTaskStore
impl !UnwindSafe for SqliteTaskStore
impl Freeze for SqliteTaskStore
impl Send for SqliteTaskStore
impl Sync for SqliteTaskStore
impl Unpin for SqliteTaskStore
impl UnsafeUnpin for SqliteTaskStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request