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
impl QueryRuntime
Sourcepub fn builder() -> QueryRuntimeBuilder
pub fn builder() -> QueryRuntimeBuilder
Sourcepub fn query<Q: Query>(&self, query: Q) -> Result<Arc<Q::Output>, QueryError>
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 loadingQueryError::Cycle- Dependency cycle detected
Sourcepub fn invalidate<Q: Query>(&self, key: &Q::CacheKey)
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.
Sourcepub fn remove_query<Q: Query>(&self, key: &Q::CacheKey)
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.
Sourcepub fn clear_cache(&self)
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.
Sourcepub fn poll<Q: Query>(
&self,
query: Q,
) -> Result<Polled<Result<Arc<Q::Output>, Arc<Error>>>, QueryError>
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), ... }).
Sourcepub fn changed_at<Q: Query>(&self, key: &Q::CacheKey) -> Option<RevisionCounter>
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
impl QueryRuntime
Sourcepub fn register_asset_locator<K, L>(&self, locator: L)where
K: AssetKey,
L: AssetLocator<K>,
pub fn register_asset_locator<K, L>(&self, locator: L)where
K: AssetKey,
L: AssetLocator<K>,
Sourcepub fn pending_assets(&self) -> Vec<PendingAsset>
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);
}
}Sourcepub fn pending_assets_of<K: AssetKey>(&self) -> Vec<K>
pub fn pending_assets_of<K: AssetKey>(&self) -> Vec<K>
Get pending assets filtered by key type.
Sourcepub fn has_pending_assets(&self) -> bool
pub fn has_pending_assets(&self) -> bool
Check if there are any pending assets.
Sourcepub fn resolve_asset<K: AssetKey>(&self, key: K, value: K::Asset)
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);Sourcepub fn resolve_asset_with_durability<K: AssetKey>(
&self,
key: K,
value: K::Asset,
durability: DurabilityLevel,
)
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.
Sourcepub fn invalidate_asset<K: AssetKey>(&self, key: &K)
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_assetSourcepub fn remove_asset<K: AssetKey>(&self, key: &K)
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.
Sourcepub fn get_asset<K: AssetKey>(
&self,
key: &K,
) -> Result<LoadingState<Arc<K::Asset>>, QueryError>
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 readyOk(LoadingState::Loading)- Asset is still loading (added to pending)Err(QueryError::MissingDependency)- Asset was not found