HostMesh

Struct HostMesh 

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

An owned mesh of hosts.

§Lifecycle

HostMesh owns host lifecycles. Callers must invoke HostMesh::shutdown for deterministic teardown.

In tests and production, prefer explicit shutdown to guarantee that host agents drop their BootstrapProcManagers and that all child procs are reaped. You can use shutdown_guard to get a wrapper which will try to do a best-effort shutdown on Drop.

Implementations§

Source§

impl HostMesh

Source

pub async fn local() -> Result<HostMesh>

Bring up a local single-host mesh and, in the launcher process, return a HostMesh handle for it.

There are two execution modes:

  • bootstrap-child mode: if Bootstrap::get_from_env() says this process was launched as a bootstrap child, we call boot.bootstrap().await, which hands control to the bootstrap logic for this process (as defined by the BootstrapCommand the parent used to spawn it). if that call returns, we log the error and terminate. this branch does not produce a HostMesh.

  • launcher mode: otherwise, we are the process that is setting up the mesh. we create a Host, spawn a HostAgent in it, and build a single-host HostMesh around that. that HostMesh is returned to the caller.

This API is intended for tests, examples, and local bring-up, not production.

TODO: fix up ownership

Source

pub async fn local_with_bootstrap( bootstrap_cmd: BootstrapCommand, ) -> Result<HostMesh>

Same as [local], but the caller supplies the BootstrapCommand instead of deriving it from the current process.

The provided bootstrap_cmd is used when spawning bootstrap children and determines the behavior of boot.bootstrap().await in those children.

Source

pub async fn local_in_process() -> Result<HostMesh>

Create a local in-process host mesh where all procs run in the current OS process.

Unlike [local] which spawns child processes for each proc, this method uses LocalProcManager to run everything in-process. This makes all actors visible in the admin tree (useful for debugging with the TUI).

This API is intended for tests, examples, and debugging.

Source

pub async fn process( extent: Extent, command: BootstrapCommand, ) -> Result<HostMesh>

Create a new process-based host mesh. Each host is represented by a local process, which manages its set of procs. This is not a true host mesh the sense that each host is not independent. The intent of process is for testing, examples, and experimentation.

The bootstrap command is used to bootstrap both hosts and processes, thus it should be a command that reaches crate::bootstrap_or_die. process is itself a valid bootstrap entry point; thus using BootstrapCommand::current works correctly as long as process is called early in the lifecycle of the process and reached unconditionally.

TODO: thread through ownership

Source

pub async fn allocate<C: Actor>( cx: &C, alloc: Box<dyn Alloc + Send + Sync>, name: &str, bootstrap_params: Option<BootstrapCommand>, ) -> Result<Self>
where C::A: Handler<MeshFailure>,

Allocate a host mesh from an Alloc. This creates a HostMesh with the same extent as the provided alloc. Allocs generate procs, and thus we define and run a Host for each proc allocated by it.

§Allocation strategy

Because HostMeshes use direct-addressed procs, and must fully control the procs they are managing, HostMesh::allocate uses a trampoline actor to launch the host, which in turn runs a crate::host_mesh::host_agent::HostAgent actor to manage the host itself. The host (and thus all of its procs) are exposed directly through a separate listening channel, established by the host.

                       ┌ ─ ─┌────────────────────┐
                            │allocated Proc:     │
                       │    │ ┌─────────────────┐│
                            │ │TrampolineActor  ││
                       │    │ │ ┌──────────────┐││
                            │ │ │Host          │││
              ┌────┬ ─ ┘    │ │ │ ┌──────────┐ │││
           ┌─▶│Proc│        │ │ │ │HostAgent │ │││
           │  └────┴ ─ ┐    │ │ │ └──────────┘ │││
           │  ┌────┐        │ │ │             ██████
┌────────┐ ├─▶│Proc│   │    │ │ └──────────────┘││ ▲
│ Client │─┤  └────┘        │ └─────────────────┘│ listening channel
└────────┘ │  ┌────┐   └ ─ ─└────────────────────┘
           ├─▶│Proc│
           │  └────┘
           │  ┌────┐
           └─▶│Proc│
              └────┘
                ▲

         `Alloc`-provided
               procs
§Lifecycle

The returned HostMesh owns the underlying hosts. Call shutdown to deterministically tear them down. If you skip shutdown, Drop will attempt best-effort cleanup only. Do not rely on Drop for correctness.

Source

pub fn take(mesh: HostMeshRef) -> Self

Take ownership of an existing host mesh reference.

Consumes the HostMeshRef, captures its region/hosts, and returns an owned HostMesh that assumes lifecycle responsibility for those hosts (i.e., will shut them down on Drop).

Source

pub async fn attach( cx: &impl Actor, name: Name, addresses: Vec<ChannelAddr>, ) -> Result<Self>

Attach to pre-existing workers and push client config.

This is the “simple bootstrap” attach protocol:

  1. Wraps the provided addresses into a HostMeshRef.
  2. Snapshots propagatable_attrs() from the client’s global config.
  3. Pushes the config to each host agent as Source::ClientOverride, with a barrier to confirm installation.
  4. Returns the owned HostMesh.

After this returns, host agents have the client’s config.

Source

pub async fn shutdown(&mut self, cx: &impl Actor) -> Result<()>

Request a clean shutdown of all hosts owned by this HostMesh.

Uses a two-phase approach:

  1. Terminate children on every host concurrently. Service infrastructure (host agent, comm proc, networking) stays alive so that forwarder flushes can still reach remote hosts.
  2. Shut down hosts concurrently. No user procs remain, so this is fast and cannot deadlock on cross-host flush timeouts.
Source

pub fn shutdown_guard(self) -> HostMeshShutdownGuard

Consumes and wraps this HostMesh with a HostMeshShutdownGuard, which will ensure shutdown is run on Drop.

Source

pub async fn stop(&mut self, cx: &impl Actor) -> Result<()>

Stop all hosts owned by this HostMesh, draining user procs but keeping worker processes and their sockets alive for reconnection.

After stop, the same worker addresses can be passed to HostMesh::attach to create a new mesh.

Source§

impl HostMesh

Source

pub fn set_bootstrap(&mut self, cmd: BootstrapCommand)

Set the bootstrap command on the underlying HostMeshRef, so that future spawn calls use it. Unlike HostMeshRef::with_bootstrap this mutates in place, preserving ownership.

Methods from Deref<Target = HostMeshRef>§

Source

pub async fn spawn<C: Actor>( &self, cx: &C, name: &str, per_host: Extent, proc_bind: Option<Vec<ProcBind>>, ) -> Result<ProcMesh>
where C::A: Handler<MeshFailure>,

Spawn a ProcMesh onto this host mesh. The per_host extent specifies the shape of the procs to spawn on each host.

proc_bind, when provided, is a per-process CPU/NUMA binding configuration. Its length must equal the number of ranks in per_host. Each entry maps binding keys (cpunodebind, membind, physcpubind, cpus) to their values. Only takes effect when running on Linux.

Currently, spawn issues direct calls to each host agent. This will be fixed by maintaining a comm actor on the host service procs themselves.

Source

pub fn name(&self) -> &Name

The name of the referenced host mesh.

Source

pub fn hosts(&self) -> &[HostRef]

The host references (channel addresses) in rank order.

Trait Implementations§

Source§

impl AsRef<HostMeshRef> for HostMesh

Source§

fn as_ref(&self) -> &HostMeshRef

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl Deref for HostMesh

Source§

type Target = HostMeshRef

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.

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> Any for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

§

fn type_name(&self) -> &'static str

§

impl<T> AnySync for T
where T: Any + Send + Sync,

§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

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

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<A, M> Handler<IndexedErasedUnbound<M>> for A
where A: Handler<M>, M: Castable,

Source§

fn handle<'life0, 'life1, 'async_trait>( &'life0 mut self, cx: &'life1 Context<'_, A>, msg: IndexedErasedUnbound<M>, ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, A: 'async_trait,

Handle the next M-typed message.
§

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

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

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
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> QuoteExt for T
where T: ?Sized,

§

fn push_quoted<'q, Q, S>(&mut self, _q: Q, s: S)
where Q: QuoteInto<T>, S: Into<Quotable<'q>>,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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
Source§

impl<M> Message for M
where M: Send + Sync + 'static,