Skip to content

Runtime API (runtime)

The runtime scope object exposes read-only process state at hook entry. Use runtime.routing() for pool-wide health and in-flight counts aligned with Route.

For why this is separate from txn, see Host API overview.

Availability

Piece When present
runtime in scope Every Rule Rhai hook run
Meaningful runtime.routing() data Pool has health.enabled: true in config

When health is disabled for a pool, views still work: configured() is true and counts reflect health-off semantics (eligible_count equals configured_count; per-backend applied is "up"). Unknown pool or backend names return empty views (configured: false).

When values are taken

When your script runs on the request hook or response hook, Conduit captures one routing and health snapshot at the start of that hook phase — before your first line of Rhai runs. The snapshot includes backend health (applied, observed, eligibility), EWMA, in-flight forward counts, and fail-open flags as they were at that moment.

It is not a view from process startup. Each runtime.routing().pool(...) or .backend(...) call in the same script reads that same snapshot — calls do not re-query live health.

What to expect Practical meaning
Captured at hook phase start Request rules or response rules begin for this query on this worker; health and routing fields reflect state then.
Frozen while the script runs Probes, conduitctl health drain/freeze, and config reload can change backends after the snapshot was taken. Your variables do not update until the next hook.
Snapshot build vs reads Building the snapshot walks configured pools/backends once at hook entry (bounded by config size, outside Rhai max_operations). Each runtime.routing().pool() / .backend() call inside the script is an O(1) read and does count toward max_operations — see Sandbox limits — Host API and max_operations.
New snapshot each hook Request hook, each response hook, and each retry response pass builds a fresh snapshot. Do not carry values from one hook to the next.
Close to the next Route pick Route uses the same health sources when it selects the next backend on this query (Route reads again at selection time, so health can move in the short gap after your script).

runtime.config_generation() (and txn.config_generation()) tell you which config generation the query is running under — useful after reload to gate new policy, not for measuring probe latency or sub-second health flaps.

Use runtime to branch policy (failover pool, retry on applied down). For live operational view, use metrics and conduitctl health — not Rhai reads on every query.

Query by name

runtime.routing() answers about pools and backends you name explicitly. Pass a pool name or backend id; Conduit returns health and routing for that target.

You call You pass You get
runtime.routing().pool(name) pool name (for example "primary") pool-wide counts and flags (eligible backends, fail-open, …)
runtime.routing().backend(pool, id) pool + backend id health and routing for that backend
runtime.routing().backend_for_attempt(...) txn.selected_pool() and txn.selected_backend_name() same, for the forward attempt that just finished

Where to get names:

  • Config and rules — literal pool names in your script ("primary", "secondary").
  • This query — txn.selected_pool() / txn.selected_backend_name() on the response hook.
  • lookup() tables — resolve qname or other keys to a pool name in data_sources:, then pass that string to runtime.routing().pool(...).
  • Several pools — name each pool in the script, or resolve names from a lookup table.

runtime

Top-level read-only methods on the runtime scope object.

Methods: runtime.config_generation() · runtime.routing()

runtime.config_generation()

Request + response hook · no args · returns i64

Snapshot generation captured when this hook run started.

runtime.routing()

Request + response hook · no args · returns RoutingRuntime

Routing and health snapshot for configured pools/backends.


RoutingRuntime

Returned by runtime.routing(). Pass a pool or backend name you already have — see Query by name.

Methods: pool(name) · backend(pool, id) · backend_for_attempt(pool, backend_id)

pool(name)

RoutingRuntime method · name: string · returns PoolRuntime

Summary for the whole pool — eligible backend count, fail-open, in-flight totals, and similar.

backend(pool, id)

RoutingRuntime method · pool, id: strings · returns BackendRuntime

Per-backend health/routing view at hook entry.

backend_for_attempt(pool, backend_id)

RoutingRuntime method · two strings · returns BackendRuntime

View for a specific pool/backend pair — use with the current attempt context.


Pool view (PoolRuntime)

Returned by runtime.routing().pool("pool_name"). Methods below return pool-wide counts and flags such as eligible_count() and fail_open_active().

Methods: configured() · configured_count() · eligible_count() · fail_open_active() · min_latency_ewma_ms() · max_outstanding()

PoolRuntime.configured()

Returns bool — true when the pool exists in the active snapshot.

PoolRuntime.configured_count()

Returns i64 — number of backends defined on the pool in config.

PoolRuntime.eligible_count()

Returns i64 — backends with applied == up (Route eligibility semantics).

PoolRuntime.fail_open_active()

Returns bool — Route is ignoring health gating for this pool (all-down or below min_eligible floor).

PoolRuntime.min_latency_ewma_ms()

Returns () (unit) when unset, else float — minimum latency EWMA among pool backends with samples.

PoolRuntime.max_outstanding()

Returns i64 — maximum in-flight forwards to any backend in the pool at hook entry.


Backend view (BackendRuntime)

Returned by runtime.routing().backend(pool, id) or backend_for_attempt(...). Methods below read fields for that named pool/backend pair.

id is the configured backend name when set and unique in the pool, otherwise ip:port (same rules as metrics labels and conduitctl health).

Methods: configured() · applied() · observed() · eligible() · frozen() · weight_factor() · outstanding() · latency_ewma_ms() · last_transition_unix_ms()

BackendRuntime.configured()

Returns bool — true when the pool/backend pair exists in the active snapshot.

BackendRuntime.applied()

Return string — "up", "down", or "unknown".

applied is what Route uses.

BackendRuntime.observed()

Return string — "up", "down", or "unknown".

Probe and passive fast-trip truth (may differ from applied when frozen/drained).

BackendRuntime.eligible()

Returns bool — true when applied == up.

BackendRuntime.frozen()

Returns bool — operator freeze/drain scope active for this backend.

BackendRuntime.outstanding()

Returns i64 — in-flight upstream forwards to this backend at hook entry.

BackendRuntime.weight_factor()

Returns float — damped latency weight factor Route applies (1.0 = no reduction). Derived from EWMA.

BackendRuntime.latency_ewma_ms()

Returns () when no probe sample yet, else float — latency EWMA in milliseconds.

BackendRuntime.last_transition_unix_ms()

Returns () when unknown, else i64 — Unix ms of last observed/applied transition.


Operator health vs script reads

Mechanism Path Use
conduitctl health / gRPC Control plane Drain, freeze, resume — changes applied and scope
runtime.routing() Hot path (Rhai) Read applied, eligible, pool-wide counts for policy
Probe logs backend health transition INFO Observe probe-driven changes in process logs

Scripts only read health through runtime.routing() for policy branching. Freeze, drain, and resume are operator control-plane actions (conduitctl health), not Rhai calls.