BootstrapProcHandle

Struct BootstrapProcHandle 

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

A handle to a proc launched by BootstrapProcManager.

BootstrapProcHandle is a lightweight supervisor for an external process: it tracks and broadcasts lifecycle state, and exposes a small control/observation surface. While it may temporarily hold a tokio::process::Child (shared behind a mutex) so the exit monitor can wait() it, it is not the unique owner of the OS process, and dropping a BootstrapProcHandle does not by itself terminate the process.

What it pairs together:

  • the logical proc identity (ProcId)
  • the live status surface (ProcStatus), available both as a synchronous snapshot (status()) and as an async stream via a tokio::sync::watch channel (watch() / changed())

Responsibilities:

  • Retain the child handle only until the exit monitor claims it, so the OS process can be awaited and its terminal status recorded.
  • Hold stdout/stderr tailers until the exit monitor takes them, then join to recover buffered output for diagnostics.
  • Update status via the mark_* transitions and broadcast changes over the watch channel so tasks can await lifecycle transitions without polling.
  • Provide the foundation for higher-level APIs like wait() (await terminal) and, later, terminate() / kill().

Notes:

  • Manager-level cleanup happens in [BootstrapProcManager::drop]: it SIGKILLs any still-recorded PIDs; we do not rely on Child::kill_on_drop.

Relationship to types:

  • ProcStatus: live status surface, updated by this handle.
  • [ProcState]/[ProcStopReason] (in alloc.rs): allocator-facing, historical event log; not directly updated by this type.

Implementations§

Source§

impl BootstrapProcHandle

Source

pub fn proc_id(&self) -> &ProcId

Return the logical proc identity in the mesh.

Source

pub fn watch(&self) -> Receiver<ProcStatus>

Create a new subscription to this proc’s status stream.

Each call returns a fresh [watch::Receiver] tied to this handle’s internal ProcStatus channel. The receiver can be awaited on (rx.changed().await) to observe lifecycle transitions as they occur.

Notes:

  • Multiple subscribers can exist simultaneously; each sees every status update in order.
  • Use BootstrapProcHandle::status for a one-off snapshot; use watch() when you need to await changes over time.
Source

pub async fn changed(&self)

Wait until this proc’s status changes.

This is a convenience wrapper around [watch::Receiver::changed]: it subscribes internally via BootstrapProcHandle::watch and awaits the next transition. If no subscribers exist or the channel is closed, this returns without error.

Typical usage:

handle.changed().await;
match handle.status() {
    ProcStatus::Running { .. } => { /* now running */ }
    ProcStatus::Stopped { .. } => { /* exited */ }
    _ => {}
}
Source

pub fn status(&self) -> ProcStatus

Return a snapshot of the current ProcStatus for this proc.

This is a live view of the lifecycle state as tracked by BootstrapProcManager. It reflects what is currently known about the underlying OS process (e.g., Starting, Running, Stopping, etc.).

Internally this reads the mutex-guarded status. Use this when you just need a synchronous snapshot; use BootstrapProcHandle::watch or BootstrapProcHandle::changed if you want to await transitions asynchronously.

Source

pub async fn wait_inner(&self) -> ProcStatus

Wait until the proc has reached a terminal state and return it.

Terminal means ProcStatus::Stopped, ProcStatus::Killed, or ProcStatus::Failed. If the current status is already terminal, returns immediately.

Non-consuming: BootstrapProcHandle is a supervisor, not the owner of the OS process, so you can call wait() from multiple tasks concurrently.

Implementation detail: listens on this handle’s watch channel. It snapshots the current status, and if not terminal awaits the next change. If the channel closes unexpectedly, returns the last observed status.

Mirrors tokio::process::Child::wait(), but yields the higher-level ProcStatus instead of an ExitStatus.

Source

pub async fn ready_inner(&self) -> Result<(), ReadyError>

Wait until the proc reaches the ProcStatus::Ready state.

If the proc hits a terminal state (ProcStatus::Stopped, ProcStatus::Killed, or ProcStatus::Failed) before ever becoming Ready, this returns Err(ReadyError::Terminal(status)). If the internal watch channel closes unexpectedly, this returns Err(ReadyError::ChannelClosed). Otherwise it returns Ok(()) when Ready is first observed.

Non-consuming: BootstrapProcHandle is a supervisor, not the owner; multiple tasks may await ready() concurrently. Stopping is not treated as terminal here; we continue waiting until Ready or a terminal state is seen.

Companion to BootstrapProcHandle::wait_inner: wait_inner() resolves on exit; ready_inner() resolves on startup.

Source

pub fn set_stream_monitors( &self, out: Option<StreamFwder>, err: Option<StreamFwder>, )

Trait Implementations§

Source§

impl Clone for BootstrapProcHandle

Source§

fn clone(&self) -> BootstrapProcHandle

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BootstrapProcHandle

Source§

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

Formats the value using the given formatter. Read more
Source§

impl ProcHandle for BootstrapProcHandle

Source§

fn ready<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<(), ReadyError<Self::TerminalStatus>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Wait until this proc first reaches the ProcStatus::Ready state.

Returns Ok(()) once Ready is observed.

If the proc transitions directly to a terminal state before becoming Ready, returns Err(ReadyError::Terminal(status)).

If the internal status watch closes unexpectedly before Ready is observed, returns Err(ReadyError::ChannelClosed).

Source§

fn wait<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Self::TerminalStatus, WaitError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Wait until this proc reaches a terminal ProcStatus.

Returns Ok(status) when a terminal state is observed (Stopped, Killed, or Failed).

If the internal status watch closes before any terminal state is seen, returns Err(WaitError::ChannelClosed).

Source§

fn terminate<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, cx: &'life1 (impl 'async_trait + Actor), timeout: Duration, reason: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<ProcStatus, TerminateError<Self::TerminalStatus>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Attempt to terminate the underlying OS process.

This drives process-level teardown only:

  • First attempts graceful shutdown via ProcAgent if available.
  • If that fails or times out, delegates to the launcher’s terminate() method, which handles SIGTERM/SIGKILL escalation.

If the process was already in a terminal state when called, returns [TerminateError::AlreadyTerminated].

§Parameters
  • timeout: Grace period to wait after graceful shutdown before escalating.
  • reason: Human-readable reason for termination.
§Returns
  • Ok(ProcStatus) if the process exited during the termination sequence.
  • Err(TerminateError) if already exited, signaling failed, or the channel was lost.
Source§

fn kill<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<ProcStatus, TerminateError<Self::TerminalStatus>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Forcibly kill the underlying OS process.

This bypasses any graceful shutdown semantics and immediately delegates to the launcher’s kill() method. It is intended as a last-resort termination mechanism when terminate() fails or when no grace period is desired.

§Behavior
  • If the process was already in a terminal state, returns [TerminateError::AlreadyTerminated].
  • Otherwise delegates to the launcher’s kill() method.
  • Then waits for the exit monitor to observe a terminal state.
§Returns
  • Ok(ProcStatus) if the process exited after kill.
  • Err(TerminateError) if already exited, signaling failed, or the channel was lost.
Source§

type Agent = ProcAgent

The agent actor type installed in the proc by the manager. Must implement both: Read more
Source§

type TerminalStatus = ProcStatus

The type of terminal status produced when the proc exits. Read more
Source§

fn proc_id(&self) -> &ProcId

The proc’s logical identity on this host.
Source§

fn addr(&self) -> Option<ChannelAddr>

The proc’s address (the one callers bind into the host router). May return None before ready() completes. Guaranteed to return Some after ready() succeeds. Read more
Source§

fn agent_ref(&self) -> Option<ActorRef<Self::Agent>>

The agent actor reference hosted in the proc. May return None before ready() completes. Guaranteed to return Some after ready() succeeds. 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
§

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

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

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

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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
§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

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