/// Run the file watching loop.
/// This receives file-changed messages from `rx`, which should have been returned by `notify::watcher`.
///
/// Whenever these events happen they'll be pushed onto `output`.
///
/// The loop will end if:
///
/// * There's an error initially finding the file
/// * The input channel `rx` is closed
///
/// Otherwise it'll go on forever. The caller doesn't need to terminate this loop as it'll stop once
/// the sender side of the file-changed messages channel is dropped. Additionally, it's ok for this
/// to fail if the file can't initially be found as it should be restarted when the path changes.
///
/// File watching will hash the target file on each change event to prevent duplicate events for the
/// same content from firing. This may cause some CPU usage cost if the target file is too big or
/// changes too often.
Run the file watching loop.
This receives file-changed messages from `rx`, which should have been returned by `notify::watcher`.

Whenever these events happen they'll be pushed onto `output`.

The loop will end if.

There's an error initially finding the file
The input channel `rx` is closed

Otherwise it'll go on forever. The caller doesn't need to terminate this loop as it'll stop once
the sender side of the file-changed messages channel is dropped. Additionally, it's ok for this
to fail if the file can't initially be found as it should be restarted when the path changes.

File watching will hash the target file on each change event to prevent duplicate events for the
same content from firing. This may cause some CPU usage cost if the target file is too big or
changes too often.
Run the file watching loop . This receives file - changed messages from ` rx ` which should have been returned by ` notify :: watcher ` . Whenever these events happen they ' ll be pushed onto ` output ` . The loop will end if . There ' s an error initially finding the file The input channel ` rx ` is closed Otherwise it ' ll go on forever . The caller doesn ' t need to terminate this loop as it ' ll stop once the sender side of the file - changed messages channel is dropped . Additionally it ' s ok for this to fail if the file can ' t initially be found as it should be restarted when the path changes . File watching will hash the target file on each change event to prevent duplicate events for the same content from firing . This may cause some CPU usage cost if the target file is too big or changes too often .
fn run_file_watch_loop(
    plugin_path: &Path,
    rx: Receiver<DebouncedEvent>,
    output: tokio::sync::mpsc::Sender<FileWatchMessage>,
) {
    let inner = || -> Result<(), std::io::Error> {
        let mut current_hash = get_file_hash(plugin_path)?;
        log::info!(
            "Initializing plugin file watch loop. Start hash: {}",
            current_hash
        );
        loop {
            match rx.recv() {
                Ok(_) => match get_file_hash(plugin_path) {
                    Ok(new_hash) => {
                        if new_hash == current_hash {
                            log::warn!("Ignoring event due to same plugin hash");
                            continue;
                        } else {
                            log::info!(
                            "Received file change event. Plug-in will be reloaded content_hash={}",
                            new_hash
                        );
                            current_hash = new_hash;
                        }
                        let output = output.clone();
                        tokio::spawn(async move {
                            if let Err(err) = output.send(FileWatchMessage::Changed).await {
                                log::error!("Failed to write change to tokio channel: {}", err);
                            }
                        });
                    }
                    Err(err) => {
                        log::error!("Failed to read file {}", err);
                    }
                },
                // Recv fails if the sender is closed, so no messages will be received
                Err(_) => {
                    log::warn!("Sender closed, stopping receiver");
                    return Ok(());
                }
            }
        }
    };
    if let Err(err) = inner() {
        log::warn!("Error in file watcher thread: {}", err);
    }
    log::info!("Stopping file watcher thread");
}
fn run_file_watch_loop ( plugin_path : & Path , rx : Receiver < DebouncedEvent > , output : tokio :: sync :: mpsc :: Sender < FileWatchMessage > , ) { let inner = | | -> Result < ( ) , std :: io :: Error > { let mut current_hash = get_file_hash ( plugin_path ) ? ; log :: info ! ( " " current_hash ) ; loop { match rx . recv ( ) { Ok ( _ ) => match get_file_hash ( plugin_path ) { Ok ( new_hash ) => { if new_hash == current_hash { log :: warn ! ( " " ) ; continue ; } else { log :: info ! ( " " new_hash ) ; current_hash = new_hash ; } let output = output . clone ( ) ; tokio :: spawn ( async move { if let Err ( err ) = output . send ( FileWatchMessage :: Changed ) . await { log :: error ! ( " " err ) ; } } ) ; } Err ( err ) => { log :: error ! ( " " err ) ; } } , // Recv fails if the sender is closed, so no messages will be received Err ( _ ) => { log :: warn ! ( " " ) ; return Ok ( ( ) ) ; } } } } ; if let Err ( err ) = inner ( ) { log :: warn ! ( " " err ) ; } log :: info ! ( " " ) ; }
Run the file watching loop.
Run the file watching loop .
plugin_path
&Path
rx
Receiver<DebouncedEvent>
output
tokio::sync::mpsc::Sender<FileWatchMessage>