QueryRuntime

Struct QueryRuntime 

Source
pub struct QueryRuntime { /* private fields */ }
Expand description

The query runtime manages query execution, caching, and dependency tracking.

This is cheap to clone - all data is behind Arc.

§Example

let runtime = QueryRuntime::new();

// Sync query execution
let result = runtime.query(MyQuery { ... })?;

// Async query execution (waits through Suspend)
let result = runtime.query_async(MyQuery { ... }).await?;

Implementations§

Source§

impl QueryRuntime

Source

pub fn new() -> Self

Create a new query runtime with default settings.

Source

pub fn builder() -> QueryRuntimeBuilder

Create a builder for customizing the runtime.

§Example
let runtime = QueryRuntime::builder()
    .error_comparator(|a, b| {
        // Custom error comparison logic
        match (a.downcast_ref::<MyError>(), b.downcast_ref::<MyError>()) {
            (Some(a), Some(b)) => a == b,
            _ => false,
        }
    })
    .build();
Source

pub fn query<Q: Query>(&self, query: Q) -> Result<Arc<Q::Output>, QueryError>

Execute a query synchronously.

Returns the cached result if valid, otherwise executes the query.

§Errors
  • QueryError::Suspend - Query is waiting for async loading
  • QueryError::Cycle - Dependency cycle detected
Source

pub fn invalidate<Q: Query>(&self, key: &Q::CacheKey)

Invalidate a query, forcing recomputation on next access.

This also invalidates any queries that depend on this one.

Source

pub fn remove_query<Q: Query>(&self, key: &Q::CacheKey)

Remove a query from the cache entirely, freeing memory.

Use this for GC when a query is no longer needed. Unlike invalidate, this removes all traces of the query from storage. The query will be recomputed from scratch on next access.

This also invalidates any queries that depend on this one.

Source

pub fn clear_cache(&self)

Clear all cached values by removing all nodes from whale.

Note: This is a relatively expensive operation as it iterates through all keys.

Source

pub fn poll<Q: Query>( &self, query: Q, ) -> Result<Polled<Result<Arc<Q::Output>, Arc<Error>>>, QueryError>

Poll a query, returning both the result and its change revision.

This is useful for implementing subscription patterns where you need to detect changes efficiently. Compare the returned revision with a previously stored value to determine if the query result has changed.

The returned Polled contains a Result<Arc<Q::Output>, Arc<anyhow::Error>> as its value, allowing you to track revision changes for both success and user error cases.

§Example
struct Subscription<Q: Query> {
    query: Q,
    last_revision: RevisionCounter,
    tx: Sender<Result<Arc<Q::Output>, Arc<anyhow::Error>>>,
}

// Polling loop
for sub in &mut subscriptions {
    let result = runtime.poll(sub.query.clone())?;
    if result.revision > sub.last_revision {
        sub.tx.send(result.value.clone())?;
        sub.last_revision = result.revision;
    }
}
§Errors

Returns Err only for system errors (Suspend, Cycle, etc.). User errors are returned as Ok(Polled { value: Err(error), ... }).

Source

pub fn changed_at<Q: Query>(&self, key: &Q::CacheKey) -> Option<RevisionCounter>

Get the change revision of a query without executing it.

Returns None if the query has never been executed.

This is useful for checking if a query has changed since the last poll without the cost of executing the query.

§Example
// Check if query has changed before deciding to poll
if let Some(rev) = runtime.changed_at::<MyQuery>(&key) {
    if rev > last_known_revision {
        let result = runtime.query(MyQuery::new(key))?;
        // Process result...
    }
}
Source§

impl QueryRuntime

Source

pub fn register_asset_locator<K, L>(&self, locator: L)
where K: AssetKey, L: AssetLocator<K>,

Register an asset locator for a specific asset key type.

Only one locator can be registered per key type. Later registrations replace earlier ones.

§Example
let runtime = QueryRuntime::new();
runtime.register_asset_locator(FileSystemLocator::new("/assets"));
Source

pub fn pending_assets(&self) -> Vec<PendingAsset>

Get an iterator over pending asset requests.

Returns assets that have been requested but not yet resolved. The user should fetch these externally and call resolve_asset().

§Example
for pending in runtime.pending_assets() {
    if let Some(path) = pending.key::<FilePath>() {
        let content = fetch_file(path);
        runtime.resolve_asset(path.clone(), content);
    }
}
Source

pub fn pending_assets_of<K: AssetKey>(&self) -> Vec<K>

Get pending assets filtered by key type.

Source

pub fn has_pending_assets(&self) -> bool

Check if there are any pending assets.

Source

pub fn resolve_asset<K: AssetKey>(&self, key: K, value: K::Asset)

Resolve an asset with its loaded value.

This marks the asset as ready and invalidates any queries that depend on it (if the value changed), triggering recomputation on next access.

This method is idempotent - resolving with the same value (via asset_eq) will not trigger downstream recomputation.

Uses the asset key’s default durability.

§Example
let content = std::fs::read_to_string(&path)?;
runtime.resolve_asset(FilePath(path), content);
Source

pub fn resolve_asset_with_durability<K: AssetKey>( &self, key: K, value: K::Asset, durability: DurabilityLevel, )

Resolve an asset with a specific durability level.

Use this to override the asset key’s default durability.

Source

pub fn invalidate_asset<K: AssetKey>(&self, key: &K)

Invalidate an asset, forcing queries to re-request it.

The asset will be marked as loading and added to pending assets. Dependent queries will suspend until the asset is resolved again.

§Example
// File was modified externally
runtime.invalidate_asset(&FilePath("config.json".into()));
// Queries depending on this asset will now suspend
// User should fetch the new value and call resolve_asset
Source

pub fn remove_asset<K: AssetKey>(&self, key: &K)

Remove an asset from the cache entirely.

Unlike invalidate_asset, this removes all traces of the asset. Dependent queries will go through the locator again on next access.

Source

pub fn get_asset<K: AssetKey>( &self, key: &K, ) -> Result<LoadingState<Arc<K::Asset>>, QueryError>

Get an asset by key without tracking dependencies.

Unlike QueryContext::asset(), this method does NOT register the caller as a dependent of the asset. Use this for direct asset access outside of query execution.

§Returns
  • Ok(LoadingState::Ready(value)) - Asset is loaded and ready
  • Ok(LoadingState::Loading) - Asset is still loading (added to pending)
  • Err(QueryError::MissingDependency) - Asset was not found

Trait Implementations§

Source§

impl Clone for QueryRuntime

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for QueryRuntime

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.