-
Notifications
You must be signed in to change notification settings - Fork 72
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
Is Concurrent Processing of JavaScript Async Tasks Feasible in rquickjs? #396
Comments
Use ctx.spawn() |
@richarddd |
Tasks can run concurrent via js promises and rust futures. Tasks cannot run in parallel within the same runtime, rquickjs is not thread safe so only a single thread can have access to the runtime at once. If you need parallel execution you will have to create multiple runtimes for each thread. If you only need concurrent execution you can use |
@DelSkayn However, what I’m struggling with now is how to use ctx.spawn to implement the scenario I mentioned above. |
So most of the time you shouldn't really have to use use std::time::Duration;
use rquickjs::{
async_with, AsyncContext, AsyncRuntime, CatchResultExt, Coerced, Ctx, Error, Function, Result,
};
#[rquickjs::function]
fn print(txt: Coerced<String>) {
println!("{}", txt.0);
}
#[rquickjs::function]
async fn read_file<'js>(path: String) -> Result<String> {
tokio::fs::read_to_string(path).await.map_err(Error::Io)
}
#[rquickjs::function]
fn timeout<'js>(ctx: Ctx<'js>, count: u32, cb: Function<'js>) -> Result<()> {
ctx.clone().spawn(async move {
tokio::time::sleep(Duration::from_millis(count as u64)).await;
if let Err(e) = cb.call::<_, ()>(()).catch(&ctx) {
println!("Timeout call returned error: {}", e)
}
});
Ok(())
}
#[tokio::main]
pub async fn main() {
let rt = AsyncRuntime::new().unwrap();
let ctx = AsyncContext::full(&rt).await.unwrap();
async_with!(ctx => |ctx| {
// define the functions for access from javascript
ctx.globals().set("read_file", js_read_file).unwrap();
ctx.globals().set("timeout", js_timeout).unwrap();
ctx.globals().set("println", js_print).unwrap();
// actually run some js.
ctx.eval_promise(r#"
// Read a file
println(await read_file('Cargo.toml'));
// set a timeout
timeout(500,() => {
println("done!")
})
"#).catch(&ctx).unwrap().into_future::<()>().await.catch(&ctx).unwrap();
})
.await;
// The above will return before running the timeout callback.
// If all futures need to befinished you must drive the runtime until it is complete.
// The call below ensures that no more futures are pending.
rt.idle().await;
} Most of the time you can just convert between rust futures and js promises and have rquickjs take care of running them. |
@DelSkayn
Does the cb here support accepting a JavaScript async function(promises) with a return value?
And if there is a return value, how can it be obtained after ctx.spawn? |
I'm exploring the possibility of batch processing JavaScript async tasks within Rust's asynchronous code in rquickjs.
msg:
*mut c_void
cannot be sent between threads safelyso Is it feasible to use Rust to perform parallel processing of JavaScript method calls?
Are there any best practices or alternative approaches you would recommend for concurrent handling of async JavaScript tasks in Rust?
Any guidance or examples would be greatly appreciated!
Thank you!
The text was updated successfully, but these errors were encountered: