Effects Guide
Overview
Effects are declarative descriptions of side effects. update() never performs IO directly.
Instead, it returns a list of effects. They are executed via the capability gateway only when the
app is driven through an EffectExecutor (see Effect Lifecycle).
Effect Structure
type Effect { kind: String, payload: String, callback_tag: String }
kind— which effect to execute (see table below)payload— data for the effect (URL, query, path, etc.)callback_tag— message tag for the result delivery
Built-in Effect Kinds
| Kind | Capability | Description |
|---|---|---|
http_request | net.fetch | HTTP GET/POST request |
db_query | db.query | Database query |
fs_read | fs.read | Read file |
fs_write | fs.write | Write file |
timer | time.now | Get current time |
random | random | Get random value |
spawn_actor | actor.spawn | Spawn child actor (see ACTORS_GUIDE.md) |
send_to_actor | actor.send | Send message to actor (not executed by any actor runtime) |
llm_call | llm.call | LLM call |
emit_ui | ui.render | Emit UI tree to host |
Returning Effects From update()
fn update(state: State, msg: Msg) -> UpdateResult {
if msg.tag == "fetch" {
UpdateResult {
state: state,
effects: [
Effect {
kind: "http_request",
payload: "https://api.example.com/data",
callback_tag: "data_received",
},
],
}
} else {
UpdateResult { state: state, effects: [] }
}
}
Effect Lifecycle
update()returnsUpdateResult { state, effects }.- Framework validates effects against the policy.
- Plain
AppRuntime::sendstops here and returns the effects to the caller.boruna framework testlikewise lists the effects without executing them. - With
AppRuntime::send_with_executor(orTestHarness::send_with_effects), anEffectExecutorruns each effect:HostEffectExecutorvia the capability gateway,MockEffectExecutorwith stub results. - Effect results are returned as new messages with
callback_tagas the tag. - The caller feeds them back;
update()handles them in the next cycle.
Multiple Effects Per Cycle
Return multiple effects in the list. They execute in order.
effects: [
Effect { kind: "http_request", payload: "url1", callback_tag: "result" },
Effect { kind: "http_request", payload: "url2", callback_tag: "result" },
Effect { kind: "http_request", payload: "url3", callback_tag: "result" },
]
Policy Constraints
Effects are checked against the app’s PolicySet:
- Only listed capabilities are allowed.
max_effects_per_cyclelimits how many effects per update.- Violations produce
FrameworkError::PolicyViolation.
Determinism
Effects themselves are deterministic data. Their execution results are logged by the capability gateway. Replay substitutes recorded results, making the entire execution deterministic.