Skip to content

Launchers

A launcher is the factory that turns a request to run a program into a live process. Programs are compiled into a node but inert; the launcher is what instantiates one on demand when a client calls Dusk.process.

What a launcher does

A launcher implements dusk_program::launcher::Launcher. It declares the program id it serves and, given a ProcessContext - the new pid, the node's namespace, and the caller's program_args - produces a Box<dyn Process>. Inside launch it downcasts the generic args to the program's concrete args type and constructs the process.

Defining a launcher

#[derive(dusk_program_proc::Launcher)] generates the launcher's identity methods - program_id, version, git_rev - from the program's metadata!. You then write the one method that builds the process:

Rust
#[derive(dusk_program_proc::Launcher, Default)]
pub struct Launcher;

#[async_trait::async_trait(?Send)]
impl dusk_program::launcher::LauncherMixin for Launcher {
    async fn launch(&mut self, process_context: ProcessContext)
        -> anyhow::Result<Box<dyn Process>> {
        Ok(Box::new(MyProcess::new(process_context)))
    }
}

The process type carries a #[process_context] field, so the ProcessContext is wired into it.

How dispatch works

A node holds a LauncherSet - a list of launchers. When Dusk.process arrives, LauncherSet::launch reads program_args.program_id() - a local read of the in-memory args message, not a network call - then walks the launcher vec for a matching id and calls its launch. There is no index or hash; dispatch is a linear scan, so launcher vecs are kept short.

Registration

An impl builds a node's LauncherSet - typically with LauncherSet::from_launchers(vec![...]) - and hands dusk_core::init::init a closure returning it. init registers the set against the namespace it starts and drops it when that namespace terminates; the impl never touches the registry itself. Which programs a node can run is exactly which launchers that set contains. See Build a custom impl.