Hot reloading

Compiling a Unit and a [RuntimeContext] are expensive operations compared to the cost of calling a function. So you should try to do this as little as possible. It is appropriate to recompile a script when the source of the script changes. This section provides you with details for how this can be done when loading scripts from the filesystem.

A typical way to accomplish this is to watch a scripts directory using the notify crate. This allow the application to generate events whenever changes to the directory are detected. See the hot_reloading example and in particular the PathReloader type.

#[path = "hot_reloading/"]
mod path_reloader;

use std::path::PathBuf;
use std::pin::pin;
use std::sync::Arc;

use anyhow::{Context as _, Result};
use rune::{Context, Vm};

async fn main() -> Result<()> {
    let root =
        PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").context("missing CARGO_MANIFEST_DIR")?);

    let context = Context::with_default_modules()?;

    let mut exit = pin!(tokio::signal::ctrl_c());
    let mut reloader = pin!(path_reloader::PathReloader::new(

    let context = Arc::new(context.runtime()?);

    let mut events = Vec::new();

    loop {
        tokio::select! {
            _ = exit.as_mut() => {
            result = reloader.as_mut().watch(&mut events) => {

        for event in events.drain(..) {
            let mut vm = Vm::new(context.clone(), event.unit);

            match event.kind {
                path_reloader::EventKind::Added => {
                    if let Err(error) =["hello"], ()) {
                        println!("Error: {}", error);
                path_reloader::EventKind::Removed => {
                    if let Err(error) =["goodbye"], ()) {
                        println!("Error: {}", error);