-
-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async functions from different modules treated as normal coroutines #418
Comments
I tried implementing this (change poll_pending to use a set value instead of an address) locally this morning, but that didn't fully solve the issue. I added many print statements throughout the relevant mlua functions and Delay (from the tokio tutorial) to figure out what's wrong and it seems that the waker does not get set correctly in this scenario. So when the Future impls for async functions defined in a different library call wake, they're doing so on the default noop waker. For async functions defined in the same library, the waker is set and used correctly. The I'm not very familiar with mlua internals/the lua c api, but it seems like maybe coroutines have their own lua sub-state and |
Yeah, this is by design. It's exactly how it should be.
Rust does not provide stable ABI, the only API we can rely on is Lua C API which is stable and consitent.
For the same reason as I explained above.
Each module and the main app have their own independent state, the |
The best way to integrate async functionality between loadable modules and the main app is to integrate independent event loops together using stable primitives. The idea is to poll coroutines normally through Lua API but recognize their The same principle is used to integrate async rust and async c++, async Lua apps (such as openresty OR neovim) and async rust modules. |
Integrating futures through FFI is not easy, you can take a look to https://docs.rs/async-ffi/latest/async_ffi/ for some other solutions outside of Lua world (just to understand scope of the problem!) |
Context
I've been slowly creating some modules to use in various projects (mostly wrapping rust libraries).
Some of them are async libraries and I want to use these modules with other lua binaries (such as love2d), so I created a simple scheduler module that just contains a tokio
Runtime
andLocalSet
and functions to add coroutines to theLocalSet
and run them all.In one of my current web projects I wanted to use lua to prototype new pages, so I made a
/lua
endpoint and a websocket endpoint to connect to a fennel repl.These endpoints pass requests from and to two lua coroutines in the same lua state.
They import modules defined in a separate
.so
file and use async functions from them.Issue
I noticed that whenever I call an async function defined in a binary/library other than the one being used to run
call_async
, it uses 100% cpu.After digging through the mlua docs and code, I believe I've tracked the issue down to the fact that the address of
ASYNC_POLL_PENDING
is used for theLua::poll_pending
value rather than a constant value.This means every binary/library has a different value for
poll_pending
.So when the
Future
impl ofAsyncThread
polls the coroutine, it doesn't recognize the return value aspoll_pending
.Instead, it treats it like a normal coroutine that has yielded and immediately calls the waker to wake up the task before returning
Poll::Pending
.Question
Is there any specific reason (such as possible security concerns) that the address of
ASYNC_POLL_PENDING
is used forpoll_pending
rather than a constant value?If there is not, would it be possible to change it to use a constant value so that async functions defined in other binaries/libraries will be recognized and run correctly when using
call_async
?The text was updated successfully, but these errors were encountered: