mlua icon indicating copy to clipboard operation
mlua copied to clipboard

set_hook doesn't work with async execution

Open b0bleet opened this issue 2 years ago • 1 comments

set_hook doesn't work properly when executing Lua with exec_async()

use anyhow::Result;
use mlua::{HookTriggers, Lua};

#[tokio::main]
async fn main() -> Result<()> {
    let lua = Lua::new();
    lua.set_hook(HookTriggers::EVERY_LINE, move |_lua, _debug| {
        println!("test hook");
        Ok(())
    });

    lua.load(
        r#"
            local x = 2 + 3
            local y = x * 63
            local z = string.len(x..", "..y)
        "#,
    )
    .exec_async()
    .await?;

    lua.remove_hook();

    Ok(())
}

b0bleet avatar Dec 24 '23 07:12 b0bleet

It's not a bug, this is how Lua works. Async execution happens in coroutines, and each coroutine need to have their own hook. Setting it in main Lua thread would only update the main thread without affecting others.

The correct code for hooks in async context would be:

async fn main() -> Result<()> {
    let lua = Lua::new();

    let func = lua
        .load(
            r#"
            local x = 2 + 3
            local y = x * 63
            local z = string.len(x..", "..y)
        "#,
        )
        .into_function()?;

    let thread = lua.create_thread(func)?;
    thread.set_hook(HookTriggers::EVERY_LINE, move |_lua, _debug| {
        println!("test hook 2");
        Ok(())
    });
    let _: () = thread.into_async(()).await?;

    lua.remove_hook();

    Ok(())
}

khvzak avatar Jan 06 '24 13:01 khvzak