pub trait ProcLauncher:
Send
+ Sync
+ 'static {
// Required methods
fn launch<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
opts: LaunchOptions,
) -> Pin<Box<dyn Future<Output = Result<LaunchResult, ProcLauncherError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn terminate<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
timeout: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), ProcLauncherError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn kill<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
) -> Pin<Box<dyn Future<Output = Result<(), ProcLauncherError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Strategy interface for launching and stopping a proc.
This trait is internal to hyperactor_mesh:
BootstrapProcManager uses it to delegate the mechanics of
starting and stopping a proc while keeping lifecycle tracking
(readiness and terminal status) centralized in the manager.
Contract:
- Readiness is determined by the bootstrap callback mechanism
(
callback_addr), not by this trait. A proc is considered ready only when it invokes the callback, regardless of its underlying execution state. - Terminal status is sourced from
LaunchResult::exit_rx:launchmust return anexit_rxthat resolves exactly once with the proc’s terminal outcome. Implementations must ensureexit_rxresolves even if setup fails after partial work (for example, if spawning succeeds but exit monitoring cannot be established). terminateandkillinitiate shutdown and return without waiting for exit. Callers observe completion by awaitingexit_rx(or a higher-level handle built on it).
Process tree semantics: A launched proc may involve wrapper processes (shell, runtime shims, sanitizers) and/or spawn descendants. Launchers should treat termination as applying to the entire launched process tree (e.g., by placing the child in its own process group and signaling the group). Callers must not assume the returned PID is the only process that needs terminating.
Required Methods§
Sourcefn launch<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
opts: LaunchOptions,
) -> Pin<Box<dyn Future<Output = Result<LaunchResult, ProcLauncherError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn launch<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
opts: LaunchOptions,
) -> Pin<Box<dyn Future<Output = Result<LaunchResult, ProcLauncherError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Launch a proc using the provided bootstrap payload and config.
Implementations must:
- Start the underlying proc/container/VM.
- Arrange for
LaunchResult::exit_rxto resolve exactly once with the terminal outcome. - Return quickly after starting the proc (readiness is handled elsewhere).
opts communicates policy/intent computed by the manager.
The launcher uses it to choose backend-specific mechanics
(pipes vs inherit, log streaming, etc.).
Sourcefn terminate<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
timeout: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), ProcLauncherError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn terminate<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
timeout: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), ProcLauncherError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Initiate graceful termination.
Semantics:
- Send a graceful termination request (SIGTERM / RPC / API call).
- Schedule escalation to
killaftertimeoutif appropriate. - Return immediately; final status is delivered through
exit_rx.
This is a fallback mechanism used when higher-level (agent-first) termination cannot be applied or fails.
Sourcefn kill<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
) -> Pin<Box<dyn Future<Output = Result<(), ProcLauncherError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn kill<'life0, 'life1, 'async_trait>(
&'life0 self,
proc_id: &'life1 ProcId,
) -> Pin<Box<dyn Future<Output = Result<(), ProcLauncherError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Initiate a force-kill.
Semantics:
- Request termination as forcefully as the backend allows.
- Return immediately; final status is delivered through
exit_rx.
The exact mechanism is backend-specific:
- Native: sends SIGKILL directly to the PID.
- Systemd: calls
StopUnit(same asterminate), which sends SIGTERM and escalates to SIGKILL after the unit’s configured timeout. There is no separate “immediate SIGKILL” API in the systemd D-Bus interface without addingKillUnit.
Note: For backends like systemd, kill() currently behaves
identically to terminate(). Callers who need a stronger
guarantee should await exit_rx with a timeout rather than
assuming immediate termination.
Idempotent behavior is preferred: killing an already-dead proc should not be treated as an error unless the backend cannot determine state.