pub struct Connection<B: BidiBinding> { /* private fields */ }Expand description
A handle to one open bidirectional subscription. Writing to the wire is the
actor’s job; this only submits commands and reads events. Generic over the
backend BidiBinding. The backend module supplies the concrete alias.
Implementations§
Source§impl Connection<BackendBinding>
impl Connection<BackendBinding>
Sourcepub async fn open<A>(api: &A, initial: Update) -> Result<Self, A::Error>where
A: XmtpMlsBidiStreams,
A::SubscribeStream: 'static,
pub async fn open<A>(api: &A, initial: Update) -> Result<Self, A::Error>where
A: XmtpMlsBidiStreams,
A::SubscribeStream: 'static,
Open the backend subscription with the initial topic update.
Source§impl<B: BidiBinding> Connection<B>
impl<B: BidiBinding> Connection<B>
Sourcepub async fn mutate(&self, mutate: B::Mutate) -> Result<(), BidiError>
pub async fn mutate(&self, mutate: B::Mutate) -> Result<(), BidiError>
Add/remove subscriptions in place. Awaits a free command slot
(backpressure is right for a state change); returns Closed once the
actor has stopped — the command receiver dies with it.
Sourcepub fn try_mutate(
&self,
mutate: B::Mutate,
) -> Result<(), TryMutateError<B::Mutate>>
pub fn try_mutate( &self, mutate: B::Mutate, ) -> Result<(), TryMutateError<B::Mutate>>
Non-blocking Self::mutate: accept the update into the command buffer or
hand it straight back. Exists for callers that must never park on this
handle — a consumer that is also the sole drainer of Self::next and
awaits mutate while events back up can deadlock against the actor
(each side blocked on the channel only the other drains). Such callers
keep their own retry queue and stay free to drain.
Full returns the mutate for the caller to retry; Closed returns it
for a post-mortem (re-open and re-subscribe from durable cursors).
Sourcepub async fn finish(&self) -> Result<(), BidiError>
pub async fn finish(&self) -> Result<(), BidiError>
Half-close the request half — signal that we are done sending. The
outbound stream ends, so mutate and probe thereafter return Closed;
any live delivery already in flight keeps arriving until the server closes
its side. Half-close ends the session. It does not wait for catch-up
targets. Use the returned targets to decide when to cancel a bounded sync.
Sourcepub async fn probe(&self) -> Result<(), BidiError>
pub async fn probe(&self) -> Result<(), BidiError>
Probe the link (e.g. right after the process resumes) with the default
deadline: N × the server’s advertised keepalive interval (a 30s-derived
fallback until Started arrives). Resolves Ok on the matching Pong,
Closed if the link is already torn down, or ProbeTimedOut if no pong
arrives in time — the half-open case this whole mechanism exists to catch.
Sourcepub async fn probe_within(&self, timeout: Duration) -> Result<(), BidiError>
pub async fn probe_within(&self, timeout: Duration) -> Result<(), BidiError>
Probe with an explicit deadline. A latency-sensitive caller — say a push
notification handler that must decide in a couple of seconds whether to
reuse the connection or re-open — passes a bound far below the default.
A tight bound trades occasional false ProbeTimedOuts for speed, which is
safe: re-opening replays from durable cursors and discards duplicates.
The timeout covers the whole probe — submitting the ping (so a stalled
wire backpressuring the command queue can’t park us) and awaiting the
pong. We deliberately don’t fail-fast on a full command queue: a transient
burst of mutates is “busy,” not “dead.”
Sourcepub async fn next(
&mut self,
) -> Option<Event<B::GroupMessage, B::WelcomeMessage>>
pub async fn next( &mut self, ) -> Option<Event<B::GroupMessage, B::WelcomeMessage>>
Next event, in wire order. None means the connection ended (server
close, network death, watchdog teardown, or reap) — resume from durable
cursors on a fresh connection.
Only resolves on an event or end-of-stream, but a half-open link cannot
leave it pending forever: the actor’s silence watchdog tears the
connection down after [PROBE_TIMEOUT_MULTIPLIER] keepalive intervals
with no inbound frame (one watchdog ping in between), and that teardown
surfaces here as None. Self::probe remains for callers that need
an answer faster than the watchdog budget — e.g. a notification
handler deciding within seconds whether to reuse the connection.
pub fn failure(&self) -> Option<Arc<ConnectionFailure>>
Trait Implementations§
Source§impl<B: BidiBinding> Drop for Connection<B>
impl<B: BidiBinding> Drop for Connection<B>
Auto Trait Implementations§
impl<B> !Freeze for Connection<B>
impl<B> !RefUnwindSafe for Connection<B>
impl<B> Send for Connection<B>
impl<B> Sync for Connection<B>
impl<B> Unpin for Connection<B>
impl<B> UnsafeUnpin for Connection<B>
impl<B> !UnwindSafe for Connection<B>
Blanket Implementations§
§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read more§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read more§fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
fn aggregate_filter<P>(self, f: P) -> Self::Outputwhere
P: AsExpression<Bool>,
Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,
§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
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> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§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<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<T> IntoSql for T
impl<T> IntoSql for T
§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].