pub struct IdempotencyLayer { /* private fields */ }Expand description
Tower layer that wires an IdempotencyStore into the request pipeline.
Since ADR 0015 slice 1 the decision itself lives at L3 in
[cratestack_exec::OpExecutor]; this layer is the HTTP adapter around
it, owning exactly the things L3 may not name — the Idempotency-Key
header, the request fingerprint, the principal derivation, and the
response shapes.
Implementations§
Source§impl IdempotencyLayer
impl IdempotencyLayer
Sourcepub fn new(store: Arc<dyn IdempotencyStore>, ttl: Duration) -> IdempotencyLayer
pub fn new(store: Arc<dyn IdempotencyStore>, ttl: Duration) -> IdempotencyLayer
Construct with a default principal fingerprint derived from the
Authorization header, falling back to the verified TCP peer address
(via axum’s ConnectInfo<SocketAddr>, requires serving through
into_make_service_with_connect_info::<SocketAddr>()) when it’s
absent. If neither is available the request is refused rather than
silently placed in a shared "anonymous" namespace (cratestack#416)
— callers running mTLS or session-cookie auth, or who cannot serve
through into_make_service_with_connect_info, must supply
[with_principal_fingerprint] explicitly.
Sourcepub fn with_principal_fingerprint(
self,
f: impl Fn(&Request<Body>) -> String + Send + Sync + 'static,
) -> IdempotencyLayer
pub fn with_principal_fingerprint( self, f: impl Fn(&Request<Body>) -> String + Send + Sync + 'static, ) -> IdempotencyLayer
Override how the layer derives a principal-scoped namespace for the idempotency key. Without this, two callers sharing a key (across tenants) would collide. The supplied closure is infallible by design — a caller who opts out of the default’s fail-closed behavior is taking explicit responsibility for the namespace it returns, including any deliberate shared bucket.
Sourcepub fn with_op_resolver(
self,
f: impl Fn(&Request<Body>) -> OpAdmission + Send + Sync + 'static,
) -> IdempotencyLayer
pub fn with_op_resolver( self, f: impl Fn(&Request<Body>) -> OpAdmission + Send + Sync + 'static, ) -> IdempotencyLayer
Teach the layer which schema op each request is about, so
@no_idempotency (and every read) can skip reservation.
Mirrors crate::ratelimit::RateLimitLayer::with_should_rate_limit_fn
— pass build_rest_op_resolver over the generated
ROUTE_TRANSPORTS, or build_rpc_op_resolver over OPS.
Not installing one is a supported configuration and changes
nothing. The default resolver reports every request as
OpAdmission::unresolved, which reserves — so an existing
consumer that never calls this method reserves exactly the set of
requests it always did. That is the property ADR 0015 slice 1’s
byte-identity bar rests on, and it is why this is opt-in rather
than wired automatically.
Trait Implementations§
Source§impl Clone for IdempotencyLayer
impl Clone for IdempotencyLayer
Source§fn clone(&self) -> IdempotencyLayer
fn clone(&self) -> IdempotencyLayer
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<S> Layer<S> for IdempotencyLayer
impl<S> Layer<S> for IdempotencyLayer
Source§type Service = IdempotencyService<S>
type Service = IdempotencyService<S>
Source§fn layer(&self, inner: S) -> <IdempotencyLayer as Layer<S>>::Service
fn layer(&self, inner: S) -> <IdempotencyLayer as Layer<S>>::Service
Auto Trait Implementations§
impl !RefUnwindSafe for IdempotencyLayer
impl !UnwindSafe for IdempotencyLayer
impl Freeze for IdempotencyLayer
impl Send for IdempotencyLayer
impl Sync for IdempotencyLayer
impl Unpin for IdempotencyLayer
impl UnsafeUnpin for IdempotencyLayer
Blanket Implementations§
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
§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§impl<'src, T> IntoMaybe<'src, T> for Twhere
T: 'src,
impl<'src, T> IntoMaybe<'src, T> for Twhere
T: 'src,
impl<T> OrderedSeq<'_, T> for Twhere
T: Clone,
§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§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();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§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();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§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();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§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();§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.
§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);§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
§type Iter<'a> = Once<&'a T>
where
T: 'a
type Iter<'a> = Once<&'a T> where T: 'a
§fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
fn contains(&self, val: &T) -> boolwhere
T: PartialEq,
§fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>where
'p: 'b,
fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>where
'p: 'b,
MaybeRef].