Jido.Sensor behaviour (Jido v2.0.0-rc.1)

View Source

Defines the behaviour and metadata macro for Sensors in the Jido system.

A Sensor is a pure behaviour that transforms external events into Signals. Sensors are stateless modules that define how to initialize, handle events, and emit signals. The runtime execution is handled by a separate SensorServer.

Usage

To define a new Sensor, use the Jido.Sensor behaviour in your module:

defmodule MySensor do
  use Jido.Sensor,
    name: "my_sensor",
    description: "Monitors a specific metric",
    schema: Zoi.object(%{
      metric: Zoi.string()
    })

  @impl true
  def init(config, _context) do
    {:ok, %{metric: config.metric, last_value: nil}}
  end

  @impl true
  def handle_event({:metric_update, value}, state) do
    signal = Jido.Signal.new!(%{
      source: "my_sensor",
      type: "metric.updated",
      data: %{value: value, previous: state.last_value}
    })
    {:ok, %{state | last_value: value}, [signal]}
  end
end

Callbacks

Implementing modules must define:

  • init/2: Initialize sensor state from config and context
  • handle_event/2: Process incoming events and emit signals

Optional callbacks:

  • terminate/2: Called when the sensor is shutting down (default: :ok)

Directives

Callbacks can return directives to request runtime actions:

  • {:schedule, interval} - Schedule next poll after interval ms
  • {:schedule, interval, payload} - Schedule with custom payload
  • {:connect, adapter} - Connect to an external source
  • {:connect, adapter, opts} - Connect with options
  • {:disconnect, adapter} - Disconnect from a source
  • {:subscribe, topic} - Subscribe to a topic/pattern
  • {:unsubscribe, topic} - Unsubscribe from a topic
  • {:emit, signal} - Emit a signal immediately

Summary

Callbacks

Handle an incoming event and produce signals.

Initialize the sensor state.

Called when the sensor is shutting down.

Types

sensor_directive()

@type sensor_directive() ::
  {:schedule, pos_integer()}
  | {:schedule, pos_integer(), term()}
  | {:connect, atom()}
  | {:connect, atom(), keyword()}
  | {:disconnect, atom()}
  | {:subscribe, term()}
  | {:unsubscribe, term()}
  | {:emit, Jido.Signal.t()}

Callbacks

handle_event(event, state)

@callback handle_event(event :: term(), state :: term()) ::
  {:ok, state :: term(), signals :: [Jido.Signal.t()]}
  | {:ok, state :: term(), signals :: [Jido.Signal.t()],
     directives :: [sensor_directive()]}
  | {:error, reason :: term()}

Handle an incoming event and produce signals.

Called when the sensor receives an event from its connected source(s). Should transform the event into zero or more signals.

Parameters

  • event - The incoming event (format depends on the source)
  • state - Current sensor state

Returns

  • {:ok, state, signals} - Updated state and signals to emit
  • {:ok, state, signals, directives} - With additional directives
  • {:error, reason} - Event handling failed

init(config, context)

@callback init(config :: map(), context :: map()) ::
  {:ok, state :: term()}
  | {:ok, state :: term(), directives :: [sensor_directive()]}
  | {:error, reason :: term()}

Initialize the sensor state.

Called when the sensor is started. Receives the validated configuration and a context map containing runtime information.

Parameters

  • config - Validated configuration map (parsed against the sensor's schema)
  • context - Runtime context (e.g., sensor id, parent process info)

Returns

  • {:ok, state} - Initial state for the sensor
  • {:ok, state, directives} - Initial state with startup directives
  • {:error, reason} - Initialization failed

terminate(reason, state)

@callback terminate(reason :: term(), state :: term()) :: :ok

Called when the sensor is shutting down.

Use this to clean up any resources. The default implementation returns :ok.

Parameters

  • reason - The shutdown reason
  • state - Current sensor state

Returns

  • :ok - Shutdown complete