T3.RPC.Reader (T3 v0.3.0)

Copy Markdown View Source

Supervised owner of reconnecting, read-only RPC subscriptions.

Add this child to your application's supervisor. :connect is a zero-arity function returning {:ok, rpc_options} and is called on every connection attempt, so tickets can be freshly minted and local credentials renewed. :streams contains maps with :key, :method, optional :payload, and optional :catch_up ({method, payload}). Only explicitly configured catch-up reads are repeated; arbitrary RPC commands are never replayed.

:on_event is a synchronous function receiving {:snapshot, key, value}, {:chunk, key, values}, or {:status, status}. It must return :ok after the data is consumed; only then is the chunk acknowledged. A callback failure stops this child so its supervisor can restart it. Do not block indefinitely or send unbounded messages to a slower consumer from this callback.

Catch-up reads run before subscriptions on each connection. Without a resume cursor, T3's shell/thread streams start with an authoritative snapshot, covering changes between the read and subscription. Other protocols need their own cursor/snapshot strategy. Snapshots/events can repeat across reconnects; reducers must tolerate duplicates. Opt in to best-effort server replay with resume: true on shell/thread stream maps. Committed sequences are injected as afterSequence on reconnect. :load_cursor (fn key -> integer_or_nil end) and :save_cursor (fn key, sequence -> :ok end) can persist checkpoints across process restarts. Checkpoints advance after consumption and before ACK; storage/callback failure stops this child. Replay may coalesce or fall back to a snapshot: this is not durable audit/billing history. payload and catch-up payloads may also be functions of the last committed sequence, preserving arbitrary supported wire options without inventing cursor fields on snapshot-only reads.

A chunk callback may return {:error, :busy} only when it has consumed none of that chunk, to defer consumption and withhold its ACK. It is retried every :consumer_retry_interval (default 100 ms), keeping the reader responsive. At most one deferred chunk per configured subscription is retained; the transport's upstream backpressure bounds further delivery. This pairs with T3.RPC.WorkQueue.enqueue/2 for optional asynchronous processing. Queue admission ACKs before execution and is not durable. Catch-up/status callbacks must still return :ok promptly.

There is no durable delivery guarantee for intermediate events while offline. Both stream completion and transport failure trigger reconnect. Backoff is exponential with jitter, bounded by :min_backoff (500 ms) and :max_backoff (30 seconds). A successfully consumed chunk resets it. :jitter defaults to 0.2 (set zero in deterministic tests).

Set :health_check to a read-only {method, payload} to detect half-open idle connections. It runs every :health_interval (30 seconds), with a :health_timeout (5 seconds). A failed probe reconnects. Disabled by default.

See the board integration guide for a complete supervision example. Credentials and callback state are omitted from process status output.

Summary

Functions

Returns a specification to start this module under a supervisor.

Return committed per-stream sequence cursors (only for resume-enabled streams).

Return :connected or :disconnected without exposing connection credentials.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

cursors(server)

Return committed per-stream sequence cursors (only for resume-enabled streams).

start_link(opts)

status(server)

Return :connected or :disconnected without exposing connection credentials.