Skip to main content

RunningApp

Struct RunningApp 

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

A started service, handed out by RustStream::start.

The handle owns the graceful teardown: dropping it without calling shutdown detaches the service (dispatch tasks keep running, nothing is drained), per the crate rule that destructors never block. The intended shape when running beside a foreground server:

use ruststream::memory::MemoryBroker;
use ruststream::runtime::{AppInfo, RustStream};

let app = RustStream::new(AppInfo::new("svc", "0.1.0")).register_broker(MemoryBroker::new());
let running = app.start().await?;
// e.g. axum::serve(listener, router)
//     .with_graceful_shutdown(running.stopping())
//     .await?;
running.shutdown().await

Implementations§

Source§

impl RunningApp

Source

pub fn stopping(&self) -> impl Future<Output = ()> + Send + 'static

Resolves when the service begins stopping on its own: a subscriber hit a fail-fast failure and tore the service down.

The future is owned ('static), so it plugs directly into another server’s graceful shutdown (for example axum’s with_graceful_shutdown), stopping the host when the messaging side dies. It does not resolve on an orderly shutdown call - the caller drives that path itself.

§Cancel safety

Cancel-safe: dropping the future loses nothing; a fresh call observes the same state.

Source

pub fn health(&self) -> HealthProbe

Hands out a HealthProbe: a cheap, cloneable view of the service’s lifecycle state for a sibling task (typically an HTTP healthz endpoint).

The probe outlives shutdown and keeps reporting the terminal state (HealthState::Stopped, or HealthState::Failed with the fail-fast diagnostic), so an orchestrator stops routing traffic to a process whose messaging side died while another task keeps the process alive.

§Examples
use axum::Router;
use axum::extract::State;
use axum::http::StatusCode;
use axum::routing::get;
use ruststream::memory::MemoryBroker;
use ruststream::runtime::{AppInfo, HealthProbe, RustStream};
use tokio::net::TcpListener;

async fn healthz(State(health): State<HealthProbe>) -> StatusCode {
    if health.is_running() {
        StatusCode::OK
    } else {
        StatusCode::SERVICE_UNAVAILABLE
    }
}

let app =
    RustStream::new(AppInfo::new("svc", "0.1.0")).register_broker(MemoryBroker::new());
let running = app.start().await?;
let routes = Router::new()
    .route("/healthz", get(healthz))
    .with_state(running.health());
axum::serve(TcpListener::bind("0.0.0.0:8080").await?, routes)
    .with_graceful_shutdown(running.stopping())
    .await?;
running.shutdown().await?;
Source

pub fn publisher<B2, S>( &self, token: Bound<B2, S>, ) -> impl Future<Output = Result<<S as PublishPolicy<<B2 as Broker>::Connected>>::Live, PairError>> + Send
where B2: Broker + 'static, S: PublishPolicy<<B2 as Broker>::Connected> + Send,

Pairs a Bound token against its broker, for sending from a sibling task while the service runs (the third home of a publisher, next to reply wiring and Out injection).

Sugar over Bound::live, anchored here because the handle existing is the witness that startup connected every registered broker.

§Errors

Returns PairError when the token’s policy fails to pair.

§Examples
use ruststream::memory::prelude::*;
use serde::Serialize;

#[derive(Serialize, Outgoing)]
#[outgoing(name = "orders")]
struct Order {
    id: u64,
}

let broker = MemoryBroker::new().bindable();
let egress = broker.bind(Publish);
let app = RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(broker, |_b| {});
let running = app.start().await?;

// The HTTP task owns this publisher and sends what its requests carry.
let publisher = running.publisher(egress).await?;
publisher.message(&Order { id: 7 }).publish().await?;

running.shutdown().await?;
Source

pub async fn shutdown(self) -> Result<(), RustStreamError>

Shuts the service down gracefully.

Runs the on_shutdown hooks, stops the dispatch loops, drains in-flight handlers and post-settle continuations (bounded by the configured shutdown timeout), shuts the brokers down in reverse registration order, then runs the after_shutdown hooks.

§Errors

Returns RustStreamError if a dispatch task panicked, a broker failed to shut down, or the service had already torn itself down on a fail-fast failure (surfaced as RustStreamError::Dispatch so the operator sees a non-zero exit, not a silent stop). A failure does not cut the teardown short: every broker is still shut down and the after_shutdown hooks still run before the first failure is returned.

Trait Implementations§

Source§

impl Debug for RunningApp

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

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
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
Source§

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

Source§

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

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

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
Source§

impl<T> PublishedThrough<DefaultSlot> for T

Source§

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

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more