Work with events
What is an event
An event is a message broadcast from one cell to all interested cells, informing them that something happened. It has a name, a handler, and a payload.
This guide puts events in practice and shows how to use them.
Event Handler
An event handler is a Rust function annotated with the #[evt] macro provided by the Myrmic SDK.
#[myrmic_sdk::evt]
fn heartbeat(_md: myrmic_sdk::Metadata) -> myrmic_sdk::Result {
// ...
Ok(())
}
#[evt] exports the annotated function as a Wasm event handler. During deployment, the runtime discovers all exported event handlers and registers them automatically. By default, the event name is the handler function name - it is the name publishers use to broadcast the event.
To override the event name, pass the name attribute to the macro:
#[myrmic_sdk::evt(name = "heartbeat")]
fn on_heartbeat(_md: myrmic_sdk::Metadata) -> myrmic_sdk::Result {
// ...
Ok(())
}
Every event handler takes Metadata as its first argument - it carries context about who published the event and which cell is running:
pub struct Metadata {
pub id: Sri, // the SRI of this cell
pub sender: Sri, // the SRI of the cell that published the event; nil when published externally (e.g. CLI)
}
Event payload
An event may carry a payload - in that case, add a second argument to the handler to receive it:
#[myrmic_sdk::evt]
fn temperature_changed(_md: myrmic_sdk::Metadata, value: f32) -> myrmic_sdk::Result {
// ...
Ok(())
}
The payload type must implement Decoder and Encoder - traits the SDK uses to deserialize and serialize the payload. Both rely on serde::Serialize and serde::Deserialize, which must also be derived. To understand why and how, see Message encoding.
Numeric primitives (f32, u32, i32, bool ...), and types provided by the SDK such as myrmic_sdk::String, myrmic_sdk::Bytes, and myrmic_sdk::JsonValue already implement it by default.
An event handler is limited to one payload argument - if you need multiple fields values, wrap them in a struct and derive myrmic_sdk::Message to automatically implement Encoder and Decoder:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, myrmic_sdk::Message)]
struct TemperatureChanged {
sensor_id: myrmic_sdk::String,
value: f32,
}
#[myrmic_sdk::evt]
fn temperature_changed(_md: myrmic_sdk::Metadata, event: TemperatureChanged) -> myrmic_sdk::Result {
let _ = myrmic_sdk::info!("sensor {} reported {:.1}°C", event.sensor_id, event.value).ok();
Ok(())
}
Publish an event from the CLI
Rather than writing a cell just to test, the CLI provides myrmic publish - a tool that broadcasts an event directly from the terminal.
It takes an event name and an optional payload, and broadcasts it to all cells with a matching handler:
# No payload
myrmic publish heartbeat
# JSON payload
myrmic publish temperature_changed '{"sensor_id":"sensor-01","value":22.5}'
The payload is sent as JSON by default. For a full reference see myrmic publish.
Publish an event from a cell
Now we see how a cell publishes an event from within its own handlers.
#[myrmic_sdk::cmd]
fn record(_md: myrmic_sdk::Metadata, value: f32) -> myrmic_sdk::Result {
let event = TemperatureChanged {
sensor_id: myrmic_sdk::String::from("sensor-01"),
value,
};
myrmic_sdk::publish("temperature_changed", &event)?;
Ok(())
}
The Myrmic SDK provides the publish function to broadcast events. It takes the event name and the payload.
publish is callable from any handler within a cell - a command handler, an event handler, or an init initialization handler.
For events with no payload, the SDK provides myrmic_sdk::Void - a zero-sized placeholder that signals no data is being sent:
#[myrmic_sdk::cmd]
fn heartbeat(_md: myrmic_sdk::Metadata) -> myrmic_sdk::Result {
myrmic_sdk::publish("heartbeat", &myrmic_sdk::Void)?;
Ok(())
}
Dispatch from an event handler
publish is non-blocking - execution continues immediately after each call. All event publishes (and command sends) made inside an event handler commit atomically together with any storage operations when the handler completes - nothing is visible to the outside until that point.
See also
- How to work with commands
- Scheduling Handlers - how to schedule work at a fixed interval or after a delay
- Message encoding
- State and Storage - working with state and storage
myrmic publishreference