Skip to main content

behavior

Attribute Macro behavior 

Source
#[behavior]
Expand description

The bare #[phoxal::behavior] attribute for a participant’s inherent impl. The bare #[phoxal::behavior] attribute on a participant’s inherent impl.

Takes no arguments (configure the participant on the struct via #[phoxal::service], #[phoxal::driver], #[phoxal::tool], or #[phoxal::simulator], and its bus-facing handles via #[derive(phoxal::Api)] on a companion Api struct). Reads the lifecycle/server helper attributes on the impl’s methods, emits a ParticipantLifecycle impl that the runner drives, and re-emits the original methods verbatim with the helper attributes stripped. A method may carry at most one helper attribute.

§Lifecycle / server attributes and their required signatures

  • #[setup] - mandatory, exactly once. An async associated function named setup taking ctx: &mut SetupContext<Self> and, optionally, the participant config; returns Result<(Self, Self::Api)>.
  • #[step(hz = N)] - at most once. async fn (&mut self, api: &mut Self::Api, step: StepContext) -> Result<()>; the scheduled control loop runs at the positive, finite frequency N.
  • #[shutdown] - at most once. An async method named shutdown taking &mut self, api: &mut Self::Api, and, optionally, ctx: ShutdownContext; returns Result<()>.
  • #[server(api = field)] - an exclusive query server: async fn (&mut self, api: &mut Self::Api, request: Req) -> ServerResult<Resp>. Serialized with #[step].
  • #[server_snapshot(api = field)] - a concurrent, read-only query server: an async associated function taking state: Snapshot<State>, api: &Self::Api, and request: Req, returning ServerResult<Resp>. Requires a #[snapshot] provider.
  • #[snapshot] - at most once. The committed-snapshot provider: a synchronous fn (&self) -> State returning the committed state.

For #[server]/#[server_snapshot] the api = field names the Api struct’s Server<Req, Resp> field being implemented; both request and response bodies must be ContractBody (checked at compile time; a query only ever reaches the handler on its own version-qualified topic key, D1, so there is no separate decode-time identity check left).

§A tool is a thin runner

A #[phoxal::tool] participant may use #[setup] and #[shutdown] (plus #[snapshot], which is inert without a server), but #[step], #[server(...)], and #[server_snapshot(...)] are the typed-graph surface and are a compile error on a tool: tools are privileged, out-of-band, thin raw-bus runners (lifecycle + participant_id + ctx.robot() + phoxal::raw), not checked participants. A tool that needs a recurring loop spawns and owns its own task from #[setup].