Skip to main content

SharedState

Struct SharedState 

Source
pub struct SharedState {
    pub system: SystemConfig,
    pub gateway: RwLock<GatewayConfig>,
    pub routes: RwLock<Vec<(RouteConfig, Arc<CompiledGraph>)>>,
    pub config_path: Option<PathBuf>,
    pub metrics: Arc<GatewayMetrics>,
    pub resources: Arc<PluginResources>,
    pub config_store: Arc<dyn ConfigStore>,
    pub debug: Arc<DebugState>,
    pub acme: ArcSwapOption<AcmeRuntime>,
    pub acme_expected: bool,
}
Expand description

Shared gateway state, accessible from both the data-plane server and the Admin API.

Wrapped in an Arc and cloned into every server task. The data plane only ever takes short read locks on routes while matching a request; write locks are taken by the Admin API and hot-reload paths when swapping in a freshly compiled route table. Route recompilation happens on [SharedState::reload] / SharedState::reload_from_disk — never on the request path.

Fields§

§system: SystemConfig

Immutable system-level configuration (system.yaml); fixed for the process lifetime.

§gateway: RwLock<GatewayConfig>

Current gateway configuration (gateway.yaml), mutated by the Admin API CRUD endpoints.

§routes: RwLock<Vec<(RouteConfig, Arc<CompiledGraph>)>>

Route table: each route paired with the compiled graph of the policy it references. Kept in declaration order; the first matching route wins.

§config_path: Option<PathBuf>

Path to gateway.yaml, if known; required for SharedState::reload_from_disk.

§metrics: Arc<GatewayMetrics>

Process-wide Prometheus registry. Compiled graphs record per-node metrics into it, the data plane records per-request metrics, and the Admin API’s /metrics endpoint renders it.

§resources: Arc<PluginResources>

Shared plugin services (metrics handle, shared clients), threaded into every plugin at policy compile time.

§config_store: Arc<dyn ConfigStore>

Backend the config is loaded from and Admin API mutations are persisted to (file by default; etcd for HA clusters).

§debug: Arc<DebugState>

Debug-mode settings and the bounded trace buffer. Written by the data plane when a request opts into tracing, read by the Admin API. Fixed at startup — system.yaml is not hot-reloaded.

§acme: ArcSwapOption<AcmeRuntime>

The running ACME runtime (managed certs, solver, renewal manager), set once at startup when system.tls.acme/sni_certs[].acme is configured. None when ACME is not in use. Drives /readyz’s placeholder gate.

§acme_expected: bool

Whether system.yaml asks for ACME-managed certificates at all (acme: present and at least one managed TLS slot). The runtime in acme is only populated once server::start_server has seeded it, which happens after the admin listener is already serving — so /readyz uses this to answer “not ready” instead of “ready” during that window.

Implementations§

Source§

impl SharedState

Source

pub fn new( system: SystemConfig, gateway: GatewayConfig, config_path: Option<PathBuf>, config_store: Arc<dyn ConfigStore>, ) -> Result<Self, String>

Creates the shared state, validating and compiling every policy up front.

Fails if any policy is invalid or a route references an unknown policy, so a successfully constructed SharedState always has a usable route table.

Source

pub async fn apply_gateway(&self, new_gw: GatewayConfig) -> Result<(), String>

Validates and compiles new_gw, then atomically swaps the consumer store, route table, and in-memory gateway config.

This is the single swap path used by every config driver (file watcher, etcd watch, Admin API commits). All fallible work — consumer-store build and policy compilation — happens before any swap, so a failure leaves the running config untouched (the last-good guarantee).

Source

fn build_candidate( gw: &GatewayConfig, resources: &Arc<PluginResources>, ) -> Result<(ConsumerStore, Vec<(RouteConfig, Arc<CompiledGraph>)>), String>

Builds everything a swap needs — consumer store and compiled route table — failing before anything is touched.

Source

pub fn validate_gateway(&self, gw: &GatewayConfig) -> Result<(), String>

Validates and compiles gw without swapping anything.

Config stores call this to reject a candidate config before persisting it, so the Admin API can return an error synchronously even when the change will be applied asynchronously by a watch.

Note: on success the candidate store registry remains loaded in resources.stores; it is only ever read during a compile and is replaced by the next one, so this is not applied config.

Source

pub fn validate_gateway_dry(&self, gw: &GatewayConfig) -> Result<(), String>

validate_gateway, but guaranteed to leave resources.stores exactly as it found it, on both success and failure.

compile_routes only restores the pre-compile store registry when it fails — on success the candidate registry is left live, because every other caller (apply_gateway, config-store commits) follows a successful validate with an apply that installs that same candidate for real. A true dry-run has no such follow-up: without this, a dry_run: true MCP write (e.g. delete_store) would durably swap in the candidate registry — tearing down a live store’s client (breaking /api/sessions/ACME redis storage until the next apply) or standing up a client for a store that was never committed — even though nothing was meant to change. Use this wherever validation must not have that side effect.

Source

pub async fn reload_from_disk(&self) -> Result<(), String>

Reloads from disk (re-reads gateway.yaml raw, keeping ${VAR} placeholders — resolution happens at compile/build time), recompiles, and swaps in the new config.

Invoked by the hot-reload file watcher. Fails without side effects if config_path is unset, the file cannot be parsed, or compilation fails.

Source

pub fn load_gateway_from_disk(&self) -> Result<GatewayConfig, String>

Parses gateway.yaml from config_path without applying it (raw, ${VAR} placeholders kept). Lets callers compare the file against the live config before a reload discards in-memory edits.

Source

fn compile_routes( gateway: &GatewayConfig, resources: &Arc<PluginResources>, ) -> Result<Vec<(RouteConfig, Arc<CompiledGraph>)>, String>

Validates and compiles every policy, then binds each route to its compiled graph. Policies shared by multiple routes are compiled once and shared via Arc.

Source

fn compile_routes_inner( gateway: &GatewayConfig, resources: &Arc<PluginResources>, ) -> Result<Vec<(RouteConfig, Arc<CompiledGraph>)>, String>

The pre-stores compile body; called with the candidate registry already swapped in.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> MaybeSend for T

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more