How to Yields execution back to the Tokio runtime, when IO blocking
use core::time::Duration;
use mlua::prelude::*;
async fn sleep<'a>(_lua: &'a Lua, _: ()) -> LuaResult<()> {
tokio::time::sleep(Duration::from_secs(1)).await;
Ok(())
}
fn main() {
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
rt.spawn(async {
loop {
println!("hello");
tokio::time::sleep(Duration::from_secs(1)).await;
}
});
rt.block_on(async move {
let lua = Lua::new();
let globals = lua.globals();
globals
.set("sleep", lua.create_async_function(sleep).unwrap())
.unwrap();
lua.load(
r#"
print("123")
while(1)
do
sleep()
print(io.read(8))
end
"#,
)
.exec_async()
.await
.unwrap();
});
}
It is IO blocking when call io.read(8). Add, tokio runtime can't dispatch.
Do you have any ideas to solve this problem?
Don't use blocking io? You can register in Lua tokio-friendly function to read stdin, using the https://docs.rs/tokio/1.15.0/tokio/io/fn.stdin.html
It is called by user.
So, I should rewrite iomodule by async function?
Do you have any way to set timeout?
How about setting O_NONBLOCK flag, when fopen? @khvzak
So, I should rewrite iomodule by async function?
Yes, ideally you should replace required functions in the io module with async variants.
Timeouts would not help because it is impossible to cancel that read (from the tokio docs).
How about setting O_NONBLOCK flag, when fopen
Not sure that undestood the question. The Lua io module code is written in C and we cannot change it.