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: SystemConfigImmutable 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: boolWhether 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§
Sourcepub fn new(
system: SystemConfig,
gateway: GatewayConfig,
config_path: Option<PathBuf>,
config_store: Arc<dyn ConfigStore>,
) -> Result<Self, String>
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.
Sourcepub async fn apply_gateway(&self, new_gw: GatewayConfig) -> Result<(), String>
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).
Sourcefn build_candidate(
gw: &GatewayConfig,
resources: &Arc<PluginResources>,
) -> Result<(ConsumerStore, Vec<(RouteConfig, Arc<CompiledGraph>)>), String>
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.
Sourcepub fn validate_gateway(&self, gw: &GatewayConfig) -> Result<(), String>
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.
Sourcepub fn validate_gateway_dry(&self, gw: &GatewayConfig) -> Result<(), String>
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.
Sourcepub async fn reload_from_disk(&self) -> Result<(), String>
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.
Sourcepub fn load_gateway_from_disk(&self) -> Result<GatewayConfig, String>
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.
Sourcefn compile_routes(
gateway: &GatewayConfig,
resources: &Arc<PluginResources>,
) -> Result<Vec<(RouteConfig, Arc<CompiledGraph>)>, String>
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.
Sourcefn compile_routes_inner(
gateway: &GatewayConfig,
resources: &Arc<PluginResources>,
) -> Result<Vec<(RouteConfig, Arc<CompiledGraph>)>, String>
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§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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