Skip to main content

InputSession

Struct InputSession 

Source
pub struct InputSession<'x, C: Config> { /* private fields */ }
Expand description

A transactional session for setting and updating input query values.

InputSession provides a batch interface for modifying input queries with automatic dirty propagation. All changes are buffered during the session lifetime and committed atomically when the session is dropped.

§Lifecycle

  1. Creation: Obtained via Engine::input_session()
    • Acquires a write lock on the computation graph
    • Increments the global timestamp to invalidate running queries
  2. Modification: Use set_input or refresh
    • Changes are buffered in memory
    • Dirty queries are tracked for later propagation
  3. Commit: Automatically triggered on drop
    • Dirty propagation executes in parallel via the Rayon thread pool
    • Write buffer is submitted to persistent storage
    • Statistics are reset and internal state is cleaned up

§Dirty Propagation

When the session ends, the engine:

  • Compares new values with stored values via fingerprint hashing
  • Marks queries whose values changed as dirty
  • Recursively marks all dependent queries as dirty
  • Ensures downstream queries will recompute on next access

§Concurrency

Only one input session can be active at a time. Creating a new session while another exists will deadlock, as the write lock cannot be acquired.

The session increments the timestamp on creation, causing any in-flight queries to become stale and await cancellation. This ensures consistency between the input changes and query results.

§Example

use qbice::Engine;

// Initial setup
{
    let mut session = engine.input_session();
    session.set_input(UserId, 42);
    session.set_input(UserName, "Alice");
} // Changes committed and dirty propagation occurs here

// Query dependent values
let profile = engine.query(UserProfile(42)).await;

// Update an input
{
    let mut session = engine.input_session();
    session.set_input(UserName, "Alice Smith"); // Only this query marked dirty
} // Dirty propagation recomputes affected queries

Implementations§

Source§

impl<C: Config> InputSession<'_, C>

Source

pub fn set_input<Q: Query>( &mut self, query: Q, new_value: Q::Value, ) -> SetInputResult

Sets the value for an input query.

This method updates the value associated with the given query. If the new value differs from the existing value (based on fingerprint comparison), the query and its dependents will be marked as dirty for recomputation.

§Behavior
  • New queries: If the query has never been set before, a new entry is created
  • Changed values: If the value fingerprint differs from the stored value, dirty propagation is scheduled
  • Timestamp management: The first change in a session increments the global timestamp

All dirty propagation happens when the InputSession is dropped, not when this method is called.

§Type Parameters
  • Q: The query type, must implement Query
§Arguments
  • query: The input query key
  • new_value: The new value to associate with this query
Source

pub async fn refresh<Q: Query>(&mut self)

Refreshes all external input queries of type Q.

This method re-executes all queries of type Q that were previously computed with [ExecutionStyle::ExternalInput]. For each query:

  1. The executor is re-invoked to fetch the latest external data
  2. The new result is compared with the old result via fingerprints
  3. Only if the result changed, the query is marked dirty for propagation
§Use Case

External input queries represent data from the outside world (files, network, databases, etc.). When you know the external data has changed, call this method to refresh and update all queries of that type.

§Example
// Assume ConfigFileQuery reads configuration from disk
// and was executed with ExecutionStyle::ExternalInput

// When you know the config file has changed:
{
    let mut session = engine.input_session();
    session.refresh::<ConfigFileQuery>().await;
} // Only changed ConfigFileQuery instances will trigger dirty
  // propagation
§Type Parameters
  • Q: The query type to refresh. Must implement Query.
Source

pub fn intern<T: StableHash + Identifiable + Send + Sync + 'static>( &self, value: T, ) -> Interned<T>

Interns a value, returning a reference-counted handle to the shared allocation.

This is a delegation to Engine::intern. See its documentation for more details.

Source

pub fn intern_unsized<T: StableHash + Identifiable + Send + Sync + 'static + ?Sized, Q: Borrow<T> + Send + Sync + 'static>( &self, value: Q, ) -> Interned<T>
where Arc<T>: From<Q>,

Interns an unsized value, returning a reference-counted handle to the shared allocation.

This is a delegation to Engine::intern_unsized. See its documentation for more details.

Trait Implementations§

Source§

impl<C: Config> Debug for InputSession<'_, C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<C: Config> Drop for InputSession<'_, C>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'x, C> Freeze for InputSession<'x, C>
where <C as Config>::BuildHasher: Freeze,

§

impl<'x, C> !RefUnwindSafe for InputSession<'x, C>

§

impl<'x, C> !Send for InputSession<'x, C>

§

impl<'x, C> Sync for InputSession<'x, C>

§

impl<'x, C> Unpin for InputSession<'x, C>
where <C as Config>::BuildHasher: Unpin,

§

impl<'x, C> !UnwindSafe for InputSession<'x, C>

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> 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

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

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

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

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. 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.