https://github.com/neon-bindings/neon/pull/1025 introduced #[neon::export]. When the task attribute is included, the body of the function is executed on the libuv worker pool and a JsPromise is returned.
The #[neon::export] macro should also return a JsPromise when the function is async. The transformation is fairly straightforward, but we need a way to spawn a future. Ideally this is done in a runtime agnostic way.
Use a Spawn trait from a public crate or write our own
Provide a method for registering a global runtime
We will need good docs for registering the runtime. Since there are a couple of gotchas:
We likely do not want distinct runtimes across workers
neon::main gets called multiple times and may attempt to register
The macro should catch some common pitfalls and give clear error messages:
task attribute cannot be used with async
FunctionContext and Handle cannot be used
Notes
Runtime will likely be registered as instance data. However, users will almost always want to share a runtime across workers. Docs should encourage creating a global static runtime and sharing that across instances.
use std::{io, sync::OnceLock};
use neon::prelude::*;
use tokio::runtime::Runtime;
#[neon::main]
fn main(mut cx: ModuleContext) -> NeonResult<()> {
static RUNTIME: OnceLock<Runtime> = OnceLock::new();
let runtime = RUNTIME
.get_or_try_init(|| Runtime::new())
.or_else(|err| cx.throw_error(err.to_string()))?;
neon::register_runtime(runtime)?;
Ok(())
}
This can be simplified by using a macro attribute and defaults.
https://github.com/neon-bindings/neon/pull/1025 introduced
#[neon::export]
. When thetask
attribute is included, the body of the function is executed on the libuv worker pool and aJsPromise
is returned.The
#[neon::export]
macro should also return aJsPromise
when the function isasync
. The transformation is fairly straightforward, but we need a way to spawn a future. Ideally this is done in a runtime agnostic way.Spawn
trait from a public crate or write our ownWe will need good docs for registering the runtime. Since there are a couple of gotchas:
neon::main
gets called multiple times and may attempt to registerThe macro should catch some common pitfalls and give clear error messages:
task
attribute cannot be used withasync
FunctionContext
andHandle
cannot be usedNotes
Runtime will likely be registered as instance data. However, users will almost always want to share a runtime across workers. Docs should encourage creating a global static runtime and sharing that across instances.
This can be simplified by using a macro attribute and defaults.
Alternatively, to avoid requiring a
#[neon::main]
just to register, a feature flag could be provided that automatically creates it.