Xqlite.Telemetry.Bridge (Xqlite v0.7.0)

View Source

Forwards multi-subscriber hook deliveries into :telemetry events.

This is the Tier B layer of the telemetry plan. The fan-out hooks (update, wal, commit, rollback, progress, plus the global log hook) deliver Erlang messages to subscribed pids. The bridge is a small GenServer that:

  1. Subscribes to the requested hooks on a connection (or to the global log hook).
  2. Receives each hook message in its mailbox.
  3. Re-emits the message as a [:xqlite, :hook, :*] telemetry event.

Each bridge/2 (or bridge_log/1) call returns a struct holding the GenServer pid and the registered subscriber handles. Pass it to unbridge/1 to tear down all subscriptions and stop the GenServer.

Opt-in

Bridges are NEVER attached automatically. Users must call bridge/2 or bridge_log/1 explicitly for the connections / log hook they care about.

When telemetry is compile-disabled (config :xqlite, :telemetry_enabled, false, the default), bridge/2 and bridge_log/1 return {:error, :telemetry_disabled} rather than silently registering hooks that produce no events.

Per-connection bridge

{:ok, bridge} =
  Xqlite.Telemetry.bridge(conn,
    hooks: [:wal, :commit, :rollback, :update, :progress],
    tag: :replica_a
  )

# ... events fire as `[:xqlite, :hook, :wal]` etc ...

:ok = Xqlite.Telemetry.unbridge(bridge)

Global log bridge

{:ok, log_bridge} = Xqlite.Telemetry.bridge_log()
:ok = Xqlite.Telemetry.unbridge(log_bridge)

What about busy_handler?

busy_handler is single-subscriber by design (its callback returns a policy decision; multi-subscriber composition is ill-defined). It is NOT included in the bridge. If you want busy events as telemetry, register your own busy handler with a forwarder pid:

forwarder = spawn_link(fn -> ... emit telemetry on receive ... end)
:ok = Xqlite.set_busy_handler(conn, forwarder, max_retries: 50)

A future split (see project_busy_handler_observer_split memory) will make the observation half multi-subscriber and bring it into the bridge then.

Summary

Functions

Returns a specification to start this module under a supervisor.

Types

hook_kind()

@type hook_kind() :: :wal | :commit | :rollback | :update | :progress | :log

scope()

@type scope() :: {:conn, reference()} | :log

t()

@type t() :: %Xqlite.Telemetry.Bridge{
  hook_handles: [{hook_kind(), non_neg_integer()}],
  pid: pid(),
  scope: scope(),
  tag: term() | nil
}

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.