Demo switching file watcher backends at runtime

This commit is contained in:
Félix Saparelli 2021-08-23 03:59:02 +12:00
parent 4a9168f5e6
commit 6cb3fc1c9a
No known key found for this signature in database
GPG Key ID: B948C4BAE44FC474
3 changed files with 77 additions and 49 deletions

67
lib/examples/demo.rs Normal file
View File

@ -0,0 +1,67 @@
use watchexec::{
action::{Action, Outcome},
config::{InitConfigBuilder, RuntimeConfig},
error::ReconfigError,
fs::Watcher,
signal::Signal,
Watchexec,
};
// Run with: `env RUST_LOG=debug cargo run --example print_out`
#[tokio::main]
async fn main() -> color_eyre::eyre::Result<()> {
tracing_subscriber::fmt::init();
color_eyre::install()?;
let mut init = InitConfigBuilder::default();
init.on_error(|err| async move {
eprintln!("Watchexec Runtime Error: {}", err);
Ok::<(), std::convert::Infallible>(())
});
let mut runtime = RuntimeConfig::default();
runtime.pathset(["src"]);
runtime.command(["date"]);
let wx = Watchexec::new(init.build()?, runtime.clone())?;
let w = wx.clone();
let config = runtime.clone();
runtime.on_action(move |action: Action| {
let mut config = config.clone();
let w = w.clone();
async move {
eprintln!("Watchexec Action: {:?}", action);
let sigs = action
.events
.iter()
.flat_map(|event| event.signals())
.collect::<Vec<_>>();
if sigs.iter().any(|sig| sig == &Signal::Interrupt) {
action.outcome(Outcome::Exit);
} else if sigs.iter().any(|sig| sig == &Signal::User1) {
eprintln!("Switching to native for funsies");
config.file_watcher(Watcher::Native).keep_action();
w.reconfigure(config)?;
} else if sigs.iter().any(|sig| sig == &Signal::User2) {
eprintln!("Switching to polling for funsies");
config.file_watcher(Watcher::Poll).keep_action();
w.reconfigure(config)?;
} else {
action.outcome(Outcome::if_running(
Outcome::both(Outcome::Stop, Outcome::Start),
Outcome::Start,
));
}
Ok::<(), ReconfigError>(())
}
});
wx.reconfigure(runtime)?;
wx.main().await??;
Ok(())
}

View File

@ -1,49 +0,0 @@
use std::convert::Infallible;
use watchexec::{
action::{Action, Outcome},
config::{InitConfigBuilder, RuntimeConfig},
signal::Signal,
Watchexec,
};
// Run with: `env RUST_LOG=debug cargo run --example print_out`
#[tokio::main]
async fn main() -> color_eyre::eyre::Result<()> {
tracing_subscriber::fmt::init();
color_eyre::install()?;
let mut init = InitConfigBuilder::default();
init.on_error(|err| async move {
eprintln!("Watchexec Runtime Error: {}", err);
Ok::<(), std::convert::Infallible>(())
});
let mut runtime = RuntimeConfig::default();
runtime.pathset(["src"]);
runtime.command(["date"]);
runtime.on_action(|action: Action| async move {
eprintln!("Watchexec Action: {:?}", action);
if action
.events
.iter()
.flat_map(|event| event.signals())
.any(|sig| sig == Signal::Interrupt)
{
action.outcome(Outcome::Exit);
} else {
action.outcome(Outcome::if_running(
Outcome::both(Outcome::Stop, Outcome::Start),
Outcome::Start,
));
}
Ok::<(), Infallible>(())
});
let wx = Watchexec::new(init.build()?, runtime)?;
wx.main().await??;
Ok(())
}

View File

@ -78,6 +78,16 @@ impl RuntimeConfig {
self.action.action_handler = Arc::new(AtomicTake::new(Box::new(handler) as _));
self
}
/// Keep the action handler the same.
///
/// This is especially useful when reconfiguring _within_ the action handler.
///
/// Passing this config to `Watchexec::new()` will cause a `CriticalError::MissingHandler`.
pub fn keep_action(&mut self) -> &mut Self {
self.action.action_handler = Arc::new(AtomicTake::empty());
self
}
}
/// Initialisation configuration for [`Watchexec`][crate::Watchexec].