DataPlane

Struct DataPlane 

Source
pub struct DataPlane { /* private fields */ }
Expand description

The proxy dataplane: reads config generations from ConfigState and keeps an UpstreamRegistry coupled to each generation.

Lifecycle: after every successful compile_and_publish, the operator (dwara-bin’s reload path) calls DataPlane::refresh, which builds a new generation pair and swaps it in atomically. In-flight requests hold an Arc to the old pair, so old pools stay alive until the last request using them completes — reloads drop nothing.

Implementations§

Source§

impl DataPlane

Source

pub fn new(state: Arc<ConfigState>) -> Arc<Self>

Build from the state’s currently published snapshot.

Source

pub fn set_state_store(&self, store: Arc<StateStore>)

Attach the DWARA_STATE_DB store (DWARA_STATE_DB deployments): credentials then come from the store’s hot-cached records instead of in-memory config hashes. Call once, before serving traffic; rebuilds the authenticator against it immediately.

Source

pub fn set_license_status(&self, status: i64)

Publish the license status gauge (DW-032): 0 = no license (OSS), 1 = valid, 2 = expired within grace, 3 = expired past grace. Set once at startup and on every reload.

Source

pub fn set_locality_context(&self, ctx: LocalityContext)

DW-094 (Ent): set the edge’s locality context (region/zone). Overrides the env-var-derived context set at construction. Applied immediately to the current registry’s balancers and to every future registry built by refresh. Used by the CP/DP edge runtime to propagate the edge’s labels (set by the controller) to the dataplane’s load balancers.

Source

pub fn state_store(&self) -> Option<Arc<StateStore>>

The DWARA_STATE_DB store when one is attached (None = pure-config credentials). Admin surface seam (DW-022): /stats reports the store’s schema version when present.

Source

pub fn set_analytics(&self, store: Arc<EmbeddedAnalytics>)

Attach the embedded analytics store (DW-043): dwara-bin opens the configured database, spawns the writer/rollup workers, and hands the store here ONCE, before serving traffic. There is no detach: analytics lifetime is the process lifetime (the database file outlives restarts; the runtime handle does not).

Source

pub fn analytics(&self) -> Option<Arc<EmbeddedAnalytics>>

The embedded analytics store when one is attached (DW-043; None = the analytics endpoints 404 and recording is a no-op). Admin surface seam.

Source

pub fn ai_runtime(&self) -> Option<Arc<AiRuntime>>

The compiled AI runtime for the current generation (DW-075; None when no ai: block). Admin surface seam for DW-080 credential pool status introspection.

Source

pub fn set_record_stream(&self, stream: Arc<AccessRecordStream>)

Attach the access-record stream (DW-121): dwara-bin constructs it ALWAYS (capacity from the config when the block is present at boot, the default otherwise) and hands it here once, before serving traffic; the flusher is spawned separately (DataPlane::spawn_record_stream_flusher). Arming is the generation’s business: this immediately applies the CURRENT compiled sink set’s enabled flag, so a stream attached after construction with sinks configured does not wait for a reload to start queuing.

Source

pub fn record_stream(&self) -> Option<Arc<AccessRecordStream>>

The access-record stream when one is attached (DW-121; None = offers are no-ops — the direct-drive tests’ shape). Scrape and diagnostics seam.

Source

pub fn stream_targets(&self) -> Receiver<StreamTargets>

A fresh receiver of the CURRENT record-stream target state (DW-121); updates on every refresh. Tests driving the flusher directly use this.

Source

pub fn spawn_record_stream_flusher( self: &Arc<Self>, shutdown: Receiver<()>, ) -> JoinHandle<()>

Spawn the record-stream flusher (DW-121): one background task draining the stream’s bounded channel into ordered batches and delivering each batch (one retry cycle per batch) to the current generation’s sinks. Exactly one flusher per dataplane (the channel’s single-consumer receiver is gone after the first); a duplicate spawn logs and returns a finished handle. The task stops on shutdown after one final drain-and-flush.

Source

pub fn set_geoip(&self, db: Arc<GeoipDb>)

Attach/replace the GeoIP database (DW-050). dwara-bin opens it at startup and the hot-reload watcher swaps it; the swap is atomic and in-flight requests keep their loaded reader.

Source

pub fn geoip(&self) -> Option<Arc<GeoipDb>>

The current GeoIP database, if one is loaded (DW-050).

Source

pub fn set_credential_pepper(&self, pepper: Option<Vec<u8>>)

Attach the per-deployment credential pepper (#124). The bytes are resolved by the CALLER (dwara-bin, through the SecretSource extension seam — the security domain never touches extensions) and threaded down here; an empty slice is treated as “no pepper” (legacy-only mode). Call once, before serving traffic; rebuilds the authenticator against it immediately.

Source

pub fn set_credential_pepper_previous(&self, pepper: Option<Vec<u8>>)

SEC-10: Set the PREVIOUS credential pepper (rotation window). During a pepper rotation, the old pepper verifies existing stored hashes while the new pepper (set via set_credential_pepper) is used for new writes. Call once, before serving traffic. An empty slice is treated as “no previous pepper” (rotation window inactive).

Source

pub fn hash_new_credential(&self, secret: &str) -> String

Hash a NEW api-key secret exactly as the config seed path does (DW-046, the admin credential-issue endpoint’s helper): hmac-sha256:<hex> when a pepper is configured (#124), legacy sha256:<hex> otherwise — the authenticator verifies either shape with the SAME pepper state, so an issued key authenticates immediately. The secret never leaves this call’s stack in the clear (hashing is one-shot; no storage of raw bytes anywhere).

Source

pub fn refresh(&self)

Rebuild the (snapshot, registry) pair from the state’s current snapshot and swap it in. Call after every successful publish. Balancer state (in-flight counters, WRR phase, slow-start clocks for unchanged endpoint addresses) carries over from the previous generation, so weight/endpoint changes take effect without a restart and without resetting live counters (DW-011).

Contract (#46): the authenticator rebuild re-resolves ${...} secret references from the CURRENT snapshot’s config, so a refresh is only meaningful after the publish that validated them. A bare refresh against a snapshot whose secret sources have since broken loud-skips the affected credentials BY DESIGN (the key stops authenticating; never stale plaintext). Both call sites — the binary’s reload path and the admin publish path — invoke it only on the success side of a publish.

DW-165 review: this inline variant resolves registry plugin sources synchronously (bounded by the resolver’s per-publish budget). Async callers that must not run blocking IO on a worker thread use Self::refresh_with_sources with resolutions produced on spawn_blocking.

Source

pub fn refresh_with_sources(&self, sources: SourceResolutions)

DW-165 review: refresh with PRE-RESOLVED registry plugin sources. The binary’s reload path runs wasm::source::resolve_sources inside tokio::task::spawn_blocking (DNS via getaddrinfo and the sync TLS reads are blocking syscalls) and hands the result here, so network IO never runs on an async worker thread. The resolutions are keyed by plugin name; the lifecycle re-checks each pinned digest against the loaded module’s checksum before trusting a handed-in path, so a resolution that predates the generation being built can only fail closed.

Source

pub fn plugin_lifecycle(&self) -> &PluginLifecycle

DW-158: read accessor for the plugin lifecycle (the /plugins status surface and tests). Read-only by design — every mutation flows through reload_plugins on generation swap, never through an accessor handed to a presentation layer.

Source

pub fn plugin_statuses(&self) -> Vec<PluginStatusEntry>

DW-158: the plugin status surface — one entry per plugin the CURRENT generation declares (config order), with kind, source, digest, lifecycle state, effective limits, declared phases, and the routes referencing it. Backs the admin GET /plugins endpoint and the CLI status section.

Source

pub fn native_plugin_registry(&self) -> &NativeRegistry

DW-157: the native filter registry. Compiled-in filters register factories here at startup (config selects one with native: on a plugin); the dataplane’s per-request chain resolves names against it.

Source

pub fn apply_service_split_weights( &self, service: &str, new_canary_weight: u64, ) -> bool

DW-091: apply new service split weights atomically (transient, reverts on config reload). Loads the current generation, clones the registry, rebuilds the split for service with the new canary weight (baseline = total - canary, keeping the total constant), and stores a new Generation. Returns true on success; false when the service has no split or the rebuild failed. The canary is the SECOND target (index 1); the baseline is the first (index 0).

Source

pub fn apply_ai_canary_weights( &self, alias: &str, new_canary_weight: u64, ) -> bool

DW-091: apply new AI canary weights atomically (transient, reverts on config reload). Loads the current generation, clones the AI runtime, rebuilds the canary split for alias with the new canary weight (baseline = total - canary, keeping the total constant), and stores a new Generation. Returns true on success; false when the alias has no canary or the rebuild failed. The canary is the SECOND version (index 1); the baseline is the first (index 0).

Source

pub fn priority_counters(&self) -> &PriorityCounters

The per-priority admission/shed counters (DW-016). Metrics exposure (DW-021) reads these; tests read them directly.

Source

pub fn observability(&self) -> &Observability

This dataplane’s observability state (DW-021): metric recording, /metrics rendering, and the access-log sampling knob.

Source

pub fn observability_arc(&self) -> Arc<Observability>

The shared handle behind Self::observability (DW-039: the WebSocket tunnel task outlives the request and needs an owned handle to record its policy outcome).

Source

pub fn events(&self) -> &Arc<EventBus>

This dataplane’s event bus (DW-044): breaker/ejection/config events emit onto it; spawn_webhook_deliverer drains it.

Source

pub fn response_cache(&self) -> &Arc<ResponseCache>

The local response cache (DW-037): lookup/store stages run from handle, the admin purge endpoint and the metrics gauge walk read from here. Shared as an Arc because stale-while-revalidate spawns background revalidations that outlive the request.

Source

pub fn webhook_targets(&self) -> Receiver<Arc<Vec<WebhookTarget>>>

A fresh receiver of the CURRENT webhook target set (DW-044); updates on every refresh. Tests driving the deliverer directly (without DataPlane::spawn_webhook_deliverer) use this.

Source

pub fn spawn_webhook_deliverer( self: &Arc<Self>, shutdown: Receiver<()>, ) -> JoinHandle<()>

Spawn the webhook deliverer (DW-044) against this dataplane’s bus, target set, and metrics: one background task that drains the event queue and POSTs matching events to the configured targets (see events::webhook for the delivery contract). Exactly one deliverer per dataplane: a second call logs and returns an already-finished handle (the bus’s single-consumer receiver is gone). The task stops on shutdown (or when the dataplane is dropped and the bus closes).

Source

pub fn quota_figures_at( &self, period_start_s: i64, period_end_s: i64, ) -> HashMap<String, QuotaFigures>

Per-consumer quota figures for one export window (DW-120): the read side of the statement’s quota columns, assembled from the CURRENT config generation’s quota blocks and the state store’s quota_counters. A budget’s figures appear only when its UTC quota window FULLY CONTAINS [period_start_s, period_end_s) (see analytics::exports’ alignment rule): a daily export carries the same-day daily counter and the month-to-date monthly counter; a monthly export carries only the monthly counter. Consumers without a quotas block, without a store, or not yet synced into the store carry no figures — never fabricated zeros.

Source

pub fn spawn_export_worker( self: &Arc<Self>, shutdown: Receiver<()>, ) -> JoinHandle<()>

Spawn the usage-report export worker (DW-120): one background task on the same interval-plus-shutdown-watch machinery as the analytics rollup cascade, reading the CURRENT config generation each tick (a reload can add, change, or remove analytics. exports without a restart) and exporting every closed window of the configured kind that has no successful run record — oldest first, so a restart backfills missed windows. No-ops without an analytics store or an exports block. Safe to abort: each export is an atomic file write plus an idempotent record.

Source

pub fn ai_budgets(&self) -> Arc<AiBudgetEngine>

The AI budget engine (DW-078): current rules over the shared reload-surviving ledger.

Source

pub fn ai_pricing(&self) -> Arc<PricingTable>

The AI pricing table (DW-079): current per-model token rates.

Source

pub fn ai_governance(&self) -> Arc<GovernanceEngine>

The AI governance engine (DW-084): current per-team model allowlists and the audit switch.

Source

pub fn ai_logging(&self) -> Option<Arc<AiLoggingEngine>>

The AI prompt/response logging engine (DW-081): current logging config (enabled, sampling, retention) and compiled redactor. None when logging is not configured (capture off, privacy-first).

Source

pub fn ai_guardrails(&self) -> Arc<GuardrailEngine>

The AI guardrail engine (DW-082): current compiled guardrail rules (prompt-injection, PII, banned-content, output schema enforcement). Empty when guardrails are not configured (every prompt and response passes through — fail-open).

Source

pub fn ai_semantic_cache(&self) -> Option<Arc<SemanticCacheEngine>>

The AI semantic cache engine (DW-083): the embedding-similarity cache. None when semantic caching is not configured or disabled. Persists across reloads (the HNSW index and cached entries survive config refreshes).

Source

pub fn registry(&self) -> Arc<UpstreamRegistry>

The current generation’s upstream registry. Used by the TLS-passthrough path (which picks endpoints through the same balancers) and by tests.

Source

pub fn canary_controller(&self) -> Option<Arc<CanaryController>>

DW-091: the current generation’s auto-canary controller (None when no canary_analysis is configured). Used by the background runner and by tests.

Source

pub fn ready(&self) -> bool

Whether the gateway is READY to serve: at least one config generation has been published successfully (generation >= 1). This is the /readyz definition (DW-013). Upstream health deliberately does NOT participate: a fully-ejected pool fail-opens rather than blackholing (DW-012), so readiness tracks the gateway’s own state, not its backends’.

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<T> AnyExt for T
where T: Any + ?Sized,

§

fn downcast_ref<T>(this: &Self) -> Option<&T>
where T: Any,

Attempts to downcast this to T behind reference
§

fn downcast_mut<T>(this: &mut Self) -> Option<&mut T>
where T: Any,

Attempts to downcast this to T behind mutable reference
§

fn downcast_rc<T>(this: Rc<Self>) -> Result<Rc<T>, Rc<Self>>
where T: Any,

Attempts to downcast this to T behind Rc pointer
§

fn downcast_arc<T>(this: Arc<Self>) -> Result<Arc<T>, Arc<Self>>
where T: Any,

Attempts to downcast this to T behind Arc pointer
§

fn downcast_box<T>(this: Box<Self>) -> Result<Box<T>, Box<Self>>
where T: Any,

Attempts to downcast this to T behind Box pointer
§

fn downcast_move<T>(this: Self) -> Option<T>
where T: Any, Self: Sized,

Attempts to downcast owned Self to T, useful only in generic context as a workaround for specialization
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
§

impl<T, X> CoerceTo<T> for X
where T: CoerceFrom<X> + ?Sized,

§

fn coerce_rc_to(self: Rc<X>) -> Rc<T>

§

fn coerce_box_to(self: Box<X>) -> Box<T>

§

fn coerce_ref_to(&self) -> &T

§

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

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> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> ServiceExt for T

§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,