Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

State

Turbo-Engine requires all function to be pure and deterministic, but sometimes one need to manage some state during the execution. State is ok as long as functions that read the state are correctly invalidated when the state changes.

To help with that Turbo Engine comes with a State<T> struct that automatically handles invalidation.

Usage

#[turbo_tasks::value]
struct SomeValue {
    immutable_value: i32,
    mutable_value: State<i32>,
}

#[turbo_tasks::value_impl]
impl SomeValue {
    #[turbo_tasks::function]
    fn new(immutable_value: i32, mutable_value: i32) -> Vc<SomeValue> {
        Self {
            immutable_value,
            mutable_value: State::new(mutable_value),
        }
        .cell()
    }

    #[turbo_tasks::function]
    fn get_mutable_value(&self) -> Vc<i32> {
        // Reading the state will make the current task depend on the state
        // Changing the state will invalidate `get_mutable_value`.
        let value = self.mutable_value.get();
        Vc::cell(value)
    }

    #[turbo_tasks::function]
    fn method(&self) {
        // Writing the state will invalidate all reader of the state
        // But only if the state has been changed.
        self.mutable_value.update_conditionally(|value: &mut i32| {
          *old += 1;
          // Return true when the value has been changed
          true
        });
        // There are more ways to update the state:

        // Sets a new value. Compared this value with the old value and only update if the value has changed.
        // Requires `PartialEq` on the value type.
        self.mutable_value.set(42);

        // Sets a new value unconditionally. Always update the state and invalidate all readers.
        // Doesn't require `PartialEq` on the value type.
        self.mutable_value.set_unconditionally(42);
    }
}

State and Persistent Caching

TODO (Not implemented yet)

State is persistent in the Persistent Cache.

Best Practice

Use State only when necessary. Prefer pure functions and immutable values.