Add method to insert events into watchexec manually

This commit is contained in:
Félix Saparelli 2021-08-24 22:20:44 +12:00
parent 9cb1f5bf79
commit 33fb691d29
No known key found for this signature in database
GPG Key ID: B948C4BAE44FC474
3 changed files with 26 additions and 3 deletions

View File

@ -29,11 +29,16 @@ pub enum CriticalError {
#[diagnostic(code(watchexec::critical::io_error))]
IoError(#[from] std::io::Error),
/// Error received when an event cannot be sent to the errors channel.
/// Error received when a runtime error cannot be sent to the errors channel.
#[error("cannot send internal runtime error: {0}")]
#[diagnostic(code(watchexec::critical::error_channel_send))]
ErrorChannelSend(#[from] mpsc::error::SendError<RuntimeError>),
/// Error received when an event cannot be sent to the events channel.
#[error("cannot send event to internal channel: {0}")]
#[diagnostic(code(watchexec::critical::event_channel_send))]
EventChannelSend(#[from] mpsc::error::SendError<Event>),
/// Error received when joining the main watchexec task.
#[error("main task join: {0}")]
#[diagnostic(code(watchexec::critical::main_task_join))]

View File

@ -14,7 +14,7 @@ use std::{
use crate::signal::Signal;
/// An event, as far as watchexec cares about.
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Event {
pub particulars: Vec<Particle>,
pub metadata: HashMap<String, Vec<String>>,

View File

@ -18,6 +18,7 @@ use crate::{
action,
config::{InitConfig, RuntimeConfig},
error::{CriticalError, ReconfigError, RuntimeError},
event::Event,
fs,
handler::{rte, Handler},
signal,
@ -29,6 +30,8 @@ pub struct Watchexec {
action_watch: watch::Sender<action::WorkingData>,
fs_watch: watch::Sender<fs::WorkingData>,
event_input: mpsc::Sender<Event>,
}
impl fmt::Debug for Watchexec {
@ -48,9 +51,12 @@ impl Watchexec {
) -> Result<Arc<Self>, CriticalError> {
debug!(?init, ?runtime, pid=%std::process::id(), "initialising");
let (ev_s, ev_r) = mpsc::channel(init.event_channel_size);
let (ac_s, ac_r) = watch::channel(take(&mut runtime.action));
let (fs_s, fs_r) = watch::channel(fs::WorkingData::default());
let event_input = ev_s.clone();
// TODO: figure out how to do this (aka start the fs work) after the main task start lock
trace!("sending initial config to fs worker");
fs_s.send(take(&mut runtime.fs))
@ -65,7 +71,6 @@ impl Watchexec {
debug!("starting main task");
let (er_s, er_r) = mpsc::channel(init.error_channel_size);
let (ev_s, ev_r) = mpsc::channel(init.event_channel_size);
let eh = replace(&mut init.error_handler, Box::new(()) as _);
@ -104,6 +109,8 @@ impl Watchexec {
action_watch: ac_s,
fs_watch: fs_s,
event_input,
}))
}
@ -114,6 +121,17 @@ impl Watchexec {
Ok(())
}
/// Inputs an [`Event`] directly.
///
/// This can be useful for testing, for custom event sources, or for one-off action triggers
/// (for example, on start).
///
/// Hint: use [`Event::default()`] to send an empty event (which won't be filtered).
pub async fn send_event(&self, event: Event) -> Result<(), CriticalError> {
self.event_input.send(event).await?;
Ok(())
}
/// Start watchexec and obtain the handle to its main task.
///
/// This must only be called once.