Skip to main content

state

Attribute Macro state 

Source
#[state]
Expand description

Defines persistent state for an entity or entity trait.

This attribute is used together with #[entity_impl] or #[entity_trait_impl] to define per-instance state that is automatically persisted.

§Usage

#[derive(Clone, Serialize, Deserialize)]
struct CounterState {
    count: i32,
}

#[entity_impl]
#[state(CounterState)]
impl Counter {
    fn init(&self, ctx: &EntityContext) -> Result<CounterState, ClusterError> {
        Ok(CounterState { count: 0 })
    }

    #[rpc]
    async fn get(&self) -> Result<i32, ClusterError> {
        Ok(self.state().count)  // Lock-free read
    }

    #[rpc]
    async fn increment(&self, amount: i32) -> Result<i32, ClusterError> {
        let mut state = self.state_mut().await;  // Acquires write lock
        state.count += amount;
        Ok(state.count)  // Auto-persisted on drop
    }
}

§Requirements

The state type must implement:

  • Clone — for creating mutable snapshots
  • serde::Serialize + serde::Deserialize — for persistence
  • Send + Sync + 'static — for async safety

§State Access

When #[state(T)] is used, the following methods are available on self:

  • self.state() — Returns arc_swap::Guard<Arc<T>> for lock-free reads. Dereferences directly to &T. Never blocks.

  • self.state_mut().await — Returns StateMutGuard<T> for mutations. Acquires an async write lock. State is automatically persisted when the guard is dropped.

§Persistence

State is automatically loaded from storage when the entity spawns and saved when StateMutGuard is dropped. For entities with traits, composite state (entity + all trait states) is saved together.