macro_rules! on_process_start {
($closure:expr) => { ... };
}Expand description
Register a FnOnce(&ProcessStartArgs) closure to be called on init!.
Components that spawn special process instances implemented on the same executable can use this macro to inject their own “main” without needing to ask the user to plug an init function on the executable main. The component can spawn an instance of the current executable with marker environment variables that identify the component’s process.
§Examples
The example below declares a “main” for a foo component and a function that spawns it.
zng_env::on_process_start!(|args| {
if args.yield_count == 0 {
return args.yield_once();
}
if std::env::var("FOO_MARKER").is_ok() {
println!("Spawned as foo!");
zng_env::exit(0);
}
});
fn main() {
zng_env::init!(); // foo_main OR
// normal main
}
pub fn spawn_foo() -> std::io::Result<()> {
std::process::Command::new(std::env::current_exe()?).env("FOO_MARKER", "").spawn()?;
Ok(())
}Note that the handler yields once, this gives a chance for all handlers to run first before the handler is called again and takes over the process. It is good practice to yield at least once to ensure handlers that are supported to affect all processes actually init, as an example, the trace recorder may never start for the process if it does not yield.
Also note the use of custom exit, it is important to call it to collaborate with on_process_exit handlers.
§App Context
This event happens on the executable process context, before any APP context starts, you can use
zng::app::on_app_start here to register a handler to be called in the app context, if and when it starts.
§Web Assembly
Crates that declare on_process_start must have the wasm_bindgen dependency to compile for the wasm32 target.
In Cargo.toml add this dependency:
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = "*"Try to match the version used by zng-env.
§Linker Optimizer Issues
The macOS system linker can “optimize” away crates that are only referenced via this macro, that is, a crate dependency that is not otherwise directly addressed by code. To workaround this issue you can add a bogus reference to the crate code, something that is not trivial to optimize away. Unfortunately this code must be added on the dependent crate, or on an intermediary dependency, if your crate is at risk of being used this way please document this issue.
See zng#437 for an example of how to fix this issue.