【问题标题】:How to execute async lua code with rlua-async?如何使用 rlua-async 执行异步 lua 代码?
【发布时间】:2020-09-25 03:14:35
【问题描述】:

我正在尝试使用rlua-async 运行/编写我现有的 rust 异步代码。遗憾的是,它没有很好的文档记录,也没有示例,但我在定义我的异步函数方面占了上风,但我无法以异步方式执行我的 lua 代码。

我创建了一个最小的存储库来重现问题here

use rlua::{Lua};
use rlua_async::{ChunkExt, ContextExt};

#[actix_rt::main]
async fn main() {
    let lua_code = "my.asyncfunc(42)";
    let lua = Lua::new();

    lua.context(|lua_ctx| {
        let globals = lua_ctx.globals();
        let map_table = lua_ctx.create_table().unwrap();
        map_table
            .set(
                "asyncfunc",
                lua_ctx
                    .create_async_function(
                        |_ctx,
                         param:
                            u32
                        | async move {
                            println!("async function called {}", param);
                            Ok(())
                        }).unwrap()).unwrap();

        globals.set("my", map_table).unwrap();
    });

    lua.context(|lua_context| async move {
        let chunk = lua_context
            .load(&lua_code);
        chunk.exec_async(lua_context).await.unwrap();
    })
        .await;
    println!("finished");
}

但我收到此错误消息:

error: lifetime may not live long enough
  --> src\main.rs:28:31
   |
28 |       lua.context(|lua_context| async move {
   |  __________________------------_^
   | |                  |          |
   | |                  |          return type of closure is impl Future
   | |                  has type `LuaContext<'1>`
29 | |         let chunk = lua_context
30 | |             .load(&lua_code);
31 | |         chunk.exec_async(lua_context).await.unwrap();
32 | |     })
   | |_____^ returning this value requires that `'1` must outlive `'2`

我真的不明白错误试图告诉我什么,也没有有用的提示,甚至没有链接文档。

闭包与闭包主体不同,需要生命周期注释?但是为什么以及如何...?

编辑:如果我改为这样调用不带异步的代码:

lua.context(|lua_context| {
    let chunk = lua_context.load(&lua_code);
    chunk.exec().unwrap();
});

它可以编译,但我在运行时出现以下恐慌:

thread 'main' panicked at 'cannot access a scoped thread local variable without calling `set` first', C:\Users\ahallmann\.cargo\registry\src\github.com-1ecc6299db9ec823\scoped-tls-1.0.0\src\lib.rs:168:9

如果我使用 create_function 定义函数,一切正常。

【问题讨论】:

  • 这是完整的错误信息吗?如果没有,可以发一下吗?
  • 是的,除了错误:由于先前的错误而中止错误:无法编译rlua-async-example
  • 你为什么不删除async move而只使用普通的execcontext 方法并不期待未来,所以如果你打算使用异步,我认为你需要在你的异步运行时使用类似 block_on 的方法。我不确定 async 应该如何与 rlua 一起工作。
  • 如果我这样做,我会在运行时收到以下错误:线程 'main' 在 'cannot access a scoped thread local variable without calling set first' 时出现恐慌,C:\Users\ahallmann\。 cargo\registry\src\github.com-1ecc6299db9ec823\scoped-tls-1.0.0\src\lib.rs:168:9
  • 这可能是您的一个依赖项中的错误。你能设置RUST_BACKTRACE=1 并发布完整的回溯吗?

标签: asynchronous rust rust-actix


【解决方案1】:

在 rlua-async 的作者的帮助下,我想通了。 问题在于 actix-rt 本身,因为它需要“block_on 调用的静态生命周期”。

如果您使用 futures 或 tokio 代替它,它工作正常:

        tokio::runtime::Runtime::new()
            .unwrap()
            .block_on(chunk.exec_async(ctx))

https://github.com/actix/actix-net/issues/201 或者 https://github.com/Ekleog/rlua-async/issues/1 了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-18
    • 2017-09-25
    • 2018-12-31
    • 2019-02-09
    • 1970-01-01
    • 2018-01-25
    • 2019-01-28
    相关资源
    最近更新 更多