pub struct RoutingSpec {
pub hostnames: Vec<RoutingHostname>,
pub backend: RoutingBackend,
pub stable_name_claim: bool,
pub priority: i32,
}Expand description
Declared external edges (DNS + Ingress) this Process exposes.
Optional on ProcessSpec — None means the Process is in-cluster-
only, matching today’s default behavior. The reconciler only
emits routing artifacts when this slot is populated.
Fields§
§hostnames: Vec<RoutingHostname>Hostnames this Process answers on. Empty list is legal but
nonsensical (no Ingress, no DNS) — operators should drop the
routing slot entirely instead. The reconciler warns on
empty hostnames.
backend: RoutingBackendSingle backend Service every hostname routes to. Per-hostname backends are a future extension; v1 keeps the simple shape.
stable_name_claim: boolWhen true, additionally emit the unprefixed form of every
hostname (${app}.${cluster}.${loc}.${domain} — no
eph_id segment) iff this Process currently holds the
ProcessTable claim for (cluster, app). At most one Process
per (cluster, app) holds the claim.
priority: i32Claim arbitration priority. Higher wins. Ties broken by
oldest creationTimestamp. Negative values legal (signals
“prefer not to hold the claim”). Default 0.
Implementations§
Source§impl RoutingSpec
impl RoutingSpec
Sourcepub fn has_hostnames(&self) -> bool
pub fn has_hostnames(&self) -> bool
True iff at least one hostname is declared. The reconciler uses this to short-circuit: empty routing ⇒ no emission.
Sourcepub fn emitted_fqdn_count(&self, claim_held: bool) -> usize
pub fn emitted_fqdn_count(&self, claim_held: bool) -> usize
Total count of FQDNs this Process will emit:
hostnames.len() per-instance + hostnames.len() stable
when the claim is held.
Sourcepub const fn form(&self) -> RoutingForm
pub const fn form(&self) -> RoutingForm
Declared routing form for this Process — the typed projection
over the Self::stable_name_claim bool through the ONE
substrate composer RoutingForm::from_is_stable. Every
downstream axis (the crate::annotations::ROUTING_FORM
annotation / label the reconciler stamps, the
routing-form-<kind> require-tag prefix family in
tatara-check, any future audit dispatcher walking
RoutingForm::ALL) reads THIS ONE projection so a shift
in how “which routing form does this spec declare intent
for” is derived lands at ONE site.
Semantics — DECLARED intent, not RESOLVED emission: this is
what the operator authored on the spec. The reconciler still
gates on the ProcessTable claim before emitting the stable
FQDN form — a stable_name_claim: true spec that loses the
claim to a higher-priority peer still form() == Stable at
this site (the declared intent), even though the
runtime-effective emission is Instance on that reconcile
tick. The routing-form-<kind> require-tag is intentionally
a spec-shape probe, not a runtime-status probe, so it stays
pinned to this projection.
Peer to [crate::classification::Classification::horizon_kind] /
[crate::classification::Classification::optimization_direction]
on the “typed projection over a stored field on ONE spec
slot → closed-set discriminator” axis — both hide the raw
wire-form field behind ONE typed projection so a future
normalization (widening Self::stable_name_claim into a
typed enum with a third variant, canonicalizing across a
new Gateway form) lands at THIS ONE site and every
downstream consumer inherits the upgrade mechanically.
Sourcepub fn has_form(&self, kind: RoutingForm) -> bool
pub fn has_form(&self, kind: RoutingForm) -> bool
Scalar-carrier presence probe on the derived
Self::form projection — true iff this routing spec’s
declared RoutingForm (as read through
RoutingForm::from_is_stable over the stable_name_claim
bool) matches the queried variant.
The one-line collapse of the
<r>.form() == kind closure body lifted to ONE substrate
owner past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold —
the nineteenth closed-set-driven prefix family in
[tatara-check]’s point-domain require-tag classifier
(routing-form-<kind>) is the first workspace-wide consumer.
The shape is a peer of
crate::lifetime::EphemeralLifetime::has_teardown_policy on
the SAME (Option-parent × defaulted-scalar-child) corner of
the workspace-wide presence-probe algebra: the parent is
Option<RoutingSpec> on crate::crd::ProcessSpec::routing
(None short-circuits every kind), and the child is a scalar
derived from a #[serde(default)] bool (stable_name_claim: false by default → RoutingForm::Instance by default).
§Sibling scalar-carrier probes
crate::spec::SignalPolicy::has_sighup_strategy— required parent × defaulted scalar child (stored).crate::classification::Classification::has_calm/crate::classification::Classification::has_data_classification— required parent × defaulted scalar child (stored).crate::classification::Classification::has_horizon_kind/crate::classification::Classification::has_optimization_direction— required parent × nested-struct-scalar-child (stored).crate::lifetime::EphemeralLifetime::has_teardown_policy— Option parent × defaulted-scalar-child (stored).- THIS — Option parent (
Option<RoutingSpec>oncrate::crd::ProcessSpec::routing) × defaulted-scalar-child (RoutingFormDERIVED from the defaulted-false boolstable_name_claim). Second occupant on the (Option-parent × defaulted-scalar-child) corner, and the FIRST occupant whose child is derived rather than stored — the shape composes through the ONERoutingForm::from_is_stableprojection so a future widening of the underlyingstable_name_claimbool into a typed enum lands atRoutingForm::from_is_stablealone and everyhas_formconsumer inherits the upgrade mechanically.
§Semantics — DECLARED form, not RESOLVED emission
has_form(kind) returns true iff self.form() == kind.
See Self::form for the “declared intent” vs
“runtime-effective emission” distinction — the probe is a
spec-shape probe, not a runtime-status probe, so a
stable_name_claim: true spec that loses the ProcessTable
claim still reads has_form(Stable) == true at this site.
The reconciler-side “actually emit stable FQDNs” gate lives
downstream at claim arbitration, not here.
§Compounding
A future third RoutingForm variant added to ALL (a
hypothetical Gateway for a future Gateway-API HTTPRoute
edge, distinct from both the per-instance and stable-claim
FQDN shapes) reaches this probe through ONE ALL entry +
one as_str arm + one from_is_stable widening alone, no
per-caller edit at the routing-form-<kind> require-tag
classifier and no per-consumer restatement of the
spec.routing.as_ref().is_some_and(|r| r.form() == kind)
closure body.
Theory anchor: THEORY.md §II.1 invariant 5 — composition
preserves proofs; the scalar-carrier presence-probe body
lives at ONE substrate site so every downstream
(routing-form-<kind> require-tag family in tatara-check,
closed-set audit dispatchers, future variant additions on
RoutingForm) binds through the SAME has(kind) shape.
THEORY.md §VI.1 — generation over composition; a future
variant lands at ONE ALL entry + one as_str arm + one
from_is_stable widening on the closed set and the probe
picks it up mechanically without further per-consumer
edits.
Trait Implementations§
Source§impl Clone for RoutingSpec
impl Clone for RoutingSpec
Source§fn clone(&self) -> RoutingSpec
fn clone(&self) -> RoutingSpec
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RoutingSpec
impl Debug for RoutingSpec
Source§impl<'de> Deserialize<'de> for RoutingSpec
impl<'de> Deserialize<'de> for RoutingSpec
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for RoutingSpec
impl JsonSchema for RoutingSpec
Source§fn schema_name() -> String
fn schema_name() -> String
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn is_referenceable() -> bool
fn is_referenceable() -> bool
$ref keyword. Read moreSource§impl Serialize for RoutingSpec
impl Serialize for RoutingSpec
Source§impl TataraDomain for RoutingSpec
impl TataraDomain for RoutingSpec
Source§fn compile_from_args(args: &[Sexp]) -> Result<Self>
fn compile_from_args(args: &[Sexp]) -> Result<Self>
Auto Trait Implementations§
impl Freeze for RoutingSpec
impl RefUnwindSafe for RoutingSpec
impl Send for RoutingSpec
impl Sync for RoutingSpec
impl Unpin for RoutingSpec
impl UnsafeUnpin for RoutingSpec
impl UnwindSafe for RoutingSpec
Blanket Implementations§
impl<T> AppData for Twhere
T: OptionalSend + OptionalSync + 'static + OptionalSerde,
impl<T> AppDataResponse for Twhere
T: OptionalSend + OptionalSync + 'static + OptionalSerde,
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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§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 moreimpl<T> OptionalSend for T
impl<T> OptionalSync for T
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);