From f705454029fed75b535d2237044dfb64d82f8ca8 Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 31 Oct 2024 09:24:30 +0800 Subject: [PATCH] feat(napi): introduce AsyncBlock to let user dispose resources after future done (#2338) --- crates/backend/src/typegen.rs | 7 +++ .../src/bindgen_runtime/js_values/buffer.rs | 1 + crates/napi/src/tokio_runtime.rs | 56 +++++++++++++++++- .../__snapshots__/typegen.spec.ts.md | 2 + .../__snapshots__/typegen.spec.ts.snap | Bin 5490 -> 5500 bytes examples/napi/example.wasi-browser.js | 48 ++++++++------- examples/napi/example.wasi.cjs | 48 ++++++++------- examples/napi/index.cjs | 1 + examples/napi/index.d.cts | 2 + examples/napi/src/typed_array.rs | 12 ++++ 10 files changed, 130 insertions(+), 47 deletions(-) diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index 1299f621..75c4ccbd 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -410,6 +410,13 @@ pub fn ty_to_ts_type( Some((rust_ty, false)) } }); + } else if rust_ty == "AsyncBlock" { + if let Some(arg) = args.first() { + ts_ty = Some((format!("Promise<{}>", arg.0), false)); + } else { + // Not NAPI-RS `AsyncBlock` + ts_ty = Some((rust_ty, false)); + } } else if let Some(&(known_ty, _, _)) = KNOWN_TYPES.get(rust_ty.as_str()) { if rust_ty == "()" && is_return_ty { ts_ty = Some(("void".to_owned(), false)); diff --git a/crates/napi/src/bindgen_runtime/js_values/buffer.rs b/crates/napi/src/bindgen_runtime/js_values/buffer.rs index 7ff433d0..c24b0aa4 100644 --- a/crates/napi/src/bindgen_runtime/js_values/buffer.rs +++ b/crates/napi/src/bindgen_runtime/js_values/buffer.rs @@ -347,6 +347,7 @@ impl Drop for Buffer { /// SAFETY: This is undefined behavior, as the JS side may always modify the underlying buffer, /// without synchronization. Also see the docs for the `AsMut` impl. unsafe impl Send for Buffer {} +unsafe impl Sync for Buffer {} impl Clone for Buffer { fn clone(&self) -> Self { diff --git a/crates/napi/src/tokio_runtime.rs b/crates/napi/src/tokio_runtime.rs index 6e77678f..bdd3a333 100644 --- a/crates/napi/src/tokio_runtime.rs +++ b/crates/napi/src/tokio_runtime.rs @@ -6,7 +6,9 @@ use std::{ use tokio::runtime::Runtime; -use crate::{sys, Error, JsDeferred, JsUnknown, NapiValue, Result}; +use crate::{ + bindgen_runtime::ToNapiValue, sys, Env, Error, JsDeferred, JsUnknown, NapiValue, Result, +}; fn create_runtime() -> Option { #[cfg(not(target_family = "wasm"))] @@ -221,3 +223,55 @@ pub fn execute_tokio_future< Ok(promise.0.value) } + +pub struct AsyncBlockBuilder< + V: ToNapiValue + Send + 'static, + F: Future> + Send + 'static, + Dispose: FnOnce(Env) + 'static, +> { + inner: F, + dispose: Option, +} + +impl< + V: ToNapiValue + Send + 'static, + F: Future> + Send + 'static, + Dispose: FnOnce(Env), + > AsyncBlockBuilder +{ + pub fn with(inner: F) -> Self { + Self { + inner, + dispose: None, + } + } + + pub fn with_dispose(mut self, dispose: Dispose) -> Self { + self.dispose = Some(dispose); + self + } + + pub fn build(self, env: Env) -> Result> { + Ok(AsyncBlock { + inner: execute_tokio_future(env.0, self.inner, |env, v| unsafe { + if let Some(dispose) = self.dispose { + let env = Env::from_raw(env); + dispose(env); + } + V::to_napi_value(env, v) + })?, + _phantom: PhantomData, + }) + } +} + +pub struct AsyncBlock { + inner: sys::napi_value, + _phantom: PhantomData, +} + +impl ToNapiValue for AsyncBlock { + unsafe fn to_napi_value(_: napi_sys::napi_env, val: Self) -> Result { + Ok(val.inner) + } +} diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md index 833cce80..0fab6a4c 100644 --- a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md +++ b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.md @@ -335,6 +335,8 @@ Generated by [AVA](https://avajs.dev). ␊ export declare function bufferPassThrough(buf: Buffer): Promise␊ ␊ + export declare function bufferWithAsyncBlock(buf: Buffer): Promise␊ + ␊ export declare function buildThreadsafeFunctionFromFunction(callback: (arg0: number, arg1: number) => number): void␊ ␊ export declare function buildThreadsafeFunctionFromFunctionCalleeHandle(callback: () => void): void␊ diff --git a/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap b/examples/napi/__tests__/__snapshots__/typegen.spec.ts.snap index 3a3c8203424fa496c02cbee16f4389fd969e2718..b4856e1dbaea9e12b8528a0f9749083ee65d42a1 100644 GIT binary patch delta 5465 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 P=1Ke?14QGjvSt7P4(YE4 delta 5477 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 bKR?qjC-rmr`$rF(C-Hv(qkX}uW@Z2Y3`4KF diff --git a/examples/napi/example.wasi-browser.js b/examples/napi/example.wasi-browser.js index 55b5efba..7077cc4d 100644 --- a/examples/napi/example.wasi-browser.js +++ b/examples/napi/example.wasi-browser.js @@ -359,29 +359,30 @@ function __napi_rs_initialize_modules(__napiInstance) { __napiInstance.exports['__napi_register__mutate_typed_array_363']?.() __napiInstance.exports['__napi_register__deref_uint8_array_364']?.() __napiInstance.exports['__napi_register__buffer_pass_through_365']?.() - __napiInstance.exports['__napi_register__array_buffer_pass_through_366']?.() - __napiInstance.exports['__napi_register__accept_slice_367']?.() - __napiInstance.exports['__napi_register__accept_arraybuffer_368']?.() - __napiInstance.exports['__napi_register__create_arraybuffer_369']?.() - __napiInstance.exports['__napi_register__u8_array_to_array_370']?.() - __napiInstance.exports['__napi_register__i8_array_to_array_371']?.() - __napiInstance.exports['__napi_register__u16_array_to_array_372']?.() - __napiInstance.exports['__napi_register__i16_array_to_array_373']?.() - __napiInstance.exports['__napi_register__u32_array_to_array_374']?.() - __napiInstance.exports['__napi_register__i32_array_to_array_375']?.() - __napiInstance.exports['__napi_register__f32_array_to_array_376']?.() - __napiInstance.exports['__napi_register__f64_array_to_array_377']?.() - __napiInstance.exports['__napi_register__u64_array_to_array_378']?.() - __napiInstance.exports['__napi_register__i64_array_to_array_379']?.() - __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_380']?.() - __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_381']?.() - __napiInstance.exports['__napi_register__AsyncBuffer_impl_382']?.() - __napiInstance.exports['__napi_register__async_reduce_buffer_383']?.() - __napiInstance.exports['__napi_register__async_buffer_to_array_384']?.() - __napiInstance.exports['__napi_register__u_init8_array_from_string_385']?.() - __napiInstance.exports['__napi_register__AsyncReader_impl_386']?.() - __napiInstance.exports['__napi_register__Reader_struct_387']?.() - __napiInstance.exports['__napi_register__Reader_impl_389']?.() + __napiInstance.exports['__napi_register__buffer_with_async_block_366']?.() + __napiInstance.exports['__napi_register__array_buffer_pass_through_367']?.() + __napiInstance.exports['__napi_register__accept_slice_368']?.() + __napiInstance.exports['__napi_register__accept_arraybuffer_369']?.() + __napiInstance.exports['__napi_register__create_arraybuffer_370']?.() + __napiInstance.exports['__napi_register__u8_array_to_array_371']?.() + __napiInstance.exports['__napi_register__i8_array_to_array_372']?.() + __napiInstance.exports['__napi_register__u16_array_to_array_373']?.() + __napiInstance.exports['__napi_register__i16_array_to_array_374']?.() + __napiInstance.exports['__napi_register__u32_array_to_array_375']?.() + __napiInstance.exports['__napi_register__i32_array_to_array_376']?.() + __napiInstance.exports['__napi_register__f32_array_to_array_377']?.() + __napiInstance.exports['__napi_register__f64_array_to_array_378']?.() + __napiInstance.exports['__napi_register__u64_array_to_array_379']?.() + __napiInstance.exports['__napi_register__i64_array_to_array_380']?.() + __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_381']?.() + __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_382']?.() + __napiInstance.exports['__napi_register__AsyncBuffer_impl_383']?.() + __napiInstance.exports['__napi_register__async_reduce_buffer_384']?.() + __napiInstance.exports['__napi_register__async_buffer_to_array_385']?.() + __napiInstance.exports['__napi_register__u_init8_array_from_string_386']?.() + __napiInstance.exports['__napi_register__AsyncReader_impl_387']?.() + __napiInstance.exports['__napi_register__Reader_struct_388']?.() + __napiInstance.exports['__napi_register__Reader_impl_390']?.() } export const Animal = __napiModule.exports.Animal export const AnimalWithDefaultConstructor = __napiModule.exports.AnimalWithDefaultConstructor @@ -453,6 +454,7 @@ export const bigintGetU64AsString = __napiModule.exports.bigintGetU64AsString export const btreeSetToJs = __napiModule.exports.btreeSetToJs export const btreeSetToRust = __napiModule.exports.btreeSetToRust export const bufferPassThrough = __napiModule.exports.bufferPassThrough +export const bufferWithAsyncBlock = __napiModule.exports.bufferWithAsyncBlock export const buildThreadsafeFunctionFromFunction = __napiModule.exports.buildThreadsafeFunctionFromFunction export const buildThreadsafeFunctionFromFunctionCalleeHandle = __napiModule.exports.buildThreadsafeFunctionFromFunctionCalleeHandle export const call0 = __napiModule.exports.call0 diff --git a/examples/napi/example.wasi.cjs b/examples/napi/example.wasi.cjs index eabcb25a..e132e565 100644 --- a/examples/napi/example.wasi.cjs +++ b/examples/napi/example.wasi.cjs @@ -383,29 +383,30 @@ function __napi_rs_initialize_modules(__napiInstance) { __napiInstance.exports['__napi_register__mutate_typed_array_363']?.() __napiInstance.exports['__napi_register__deref_uint8_array_364']?.() __napiInstance.exports['__napi_register__buffer_pass_through_365']?.() - __napiInstance.exports['__napi_register__array_buffer_pass_through_366']?.() - __napiInstance.exports['__napi_register__accept_slice_367']?.() - __napiInstance.exports['__napi_register__accept_arraybuffer_368']?.() - __napiInstance.exports['__napi_register__create_arraybuffer_369']?.() - __napiInstance.exports['__napi_register__u8_array_to_array_370']?.() - __napiInstance.exports['__napi_register__i8_array_to_array_371']?.() - __napiInstance.exports['__napi_register__u16_array_to_array_372']?.() - __napiInstance.exports['__napi_register__i16_array_to_array_373']?.() - __napiInstance.exports['__napi_register__u32_array_to_array_374']?.() - __napiInstance.exports['__napi_register__i32_array_to_array_375']?.() - __napiInstance.exports['__napi_register__f32_array_to_array_376']?.() - __napiInstance.exports['__napi_register__f64_array_to_array_377']?.() - __napiInstance.exports['__napi_register__u64_array_to_array_378']?.() - __napiInstance.exports['__napi_register__i64_array_to_array_379']?.() - __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_380']?.() - __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_381']?.() - __napiInstance.exports['__napi_register__AsyncBuffer_impl_382']?.() - __napiInstance.exports['__napi_register__async_reduce_buffer_383']?.() - __napiInstance.exports['__napi_register__async_buffer_to_array_384']?.() - __napiInstance.exports['__napi_register__u_init8_array_from_string_385']?.() - __napiInstance.exports['__napi_register__AsyncReader_impl_386']?.() - __napiInstance.exports['__napi_register__Reader_struct_387']?.() - __napiInstance.exports['__napi_register__Reader_impl_389']?.() + __napiInstance.exports['__napi_register__buffer_with_async_block_366']?.() + __napiInstance.exports['__napi_register__array_buffer_pass_through_367']?.() + __napiInstance.exports['__napi_register__accept_slice_368']?.() + __napiInstance.exports['__napi_register__accept_arraybuffer_369']?.() + __napiInstance.exports['__napi_register__create_arraybuffer_370']?.() + __napiInstance.exports['__napi_register__u8_array_to_array_371']?.() + __napiInstance.exports['__napi_register__i8_array_to_array_372']?.() + __napiInstance.exports['__napi_register__u16_array_to_array_373']?.() + __napiInstance.exports['__napi_register__i16_array_to_array_374']?.() + __napiInstance.exports['__napi_register__u32_array_to_array_375']?.() + __napiInstance.exports['__napi_register__i32_array_to_array_376']?.() + __napiInstance.exports['__napi_register__f32_array_to_array_377']?.() + __napiInstance.exports['__napi_register__f64_array_to_array_378']?.() + __napiInstance.exports['__napi_register__u64_array_to_array_379']?.() + __napiInstance.exports['__napi_register__i64_array_to_array_380']?.() + __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_381']?.() + __napiInstance.exports['__napi_register__accept_uint8_clamped_slice_and_buffer_slice_382']?.() + __napiInstance.exports['__napi_register__AsyncBuffer_impl_383']?.() + __napiInstance.exports['__napi_register__async_reduce_buffer_384']?.() + __napiInstance.exports['__napi_register__async_buffer_to_array_385']?.() + __napiInstance.exports['__napi_register__u_init8_array_from_string_386']?.() + __napiInstance.exports['__napi_register__AsyncReader_impl_387']?.() + __napiInstance.exports['__napi_register__Reader_struct_388']?.() + __napiInstance.exports['__napi_register__Reader_impl_390']?.() } module.exports.Animal = __napiModule.exports.Animal module.exports.AnimalWithDefaultConstructor = __napiModule.exports.AnimalWithDefaultConstructor @@ -477,6 +478,7 @@ module.exports.bigintGetU64AsString = __napiModule.exports.bigintGetU64AsString module.exports.btreeSetToJs = __napiModule.exports.btreeSetToJs module.exports.btreeSetToRust = __napiModule.exports.btreeSetToRust module.exports.bufferPassThrough = __napiModule.exports.bufferPassThrough +module.exports.bufferWithAsyncBlock = __napiModule.exports.bufferWithAsyncBlock module.exports.buildThreadsafeFunctionFromFunction = __napiModule.exports.buildThreadsafeFunctionFromFunction module.exports.buildThreadsafeFunctionFromFunctionCalleeHandle = __napiModule.exports.buildThreadsafeFunctionFromFunctionCalleeHandle module.exports.call0 = __napiModule.exports.call0 diff --git a/examples/napi/index.cjs b/examples/napi/index.cjs index 8eb015ab..3b23ac1e 100644 --- a/examples/napi/index.cjs +++ b/examples/napi/index.cjs @@ -434,6 +434,7 @@ module.exports.bigintGetU64AsString = nativeBinding.bigintGetU64AsString module.exports.btreeSetToJs = nativeBinding.btreeSetToJs module.exports.btreeSetToRust = nativeBinding.btreeSetToRust module.exports.bufferPassThrough = nativeBinding.bufferPassThrough +module.exports.bufferWithAsyncBlock = nativeBinding.bufferWithAsyncBlock module.exports.buildThreadsafeFunctionFromFunction = nativeBinding.buildThreadsafeFunctionFromFunction module.exports.buildThreadsafeFunctionFromFunctionCalleeHandle = nativeBinding.buildThreadsafeFunctionFromFunctionCalleeHandle module.exports.call0 = nativeBinding.call0 diff --git a/examples/napi/index.d.cts b/examples/napi/index.d.cts index da567b11..68158323 100644 --- a/examples/napi/index.d.cts +++ b/examples/napi/index.d.cts @@ -325,6 +325,8 @@ export declare function btreeSetToRust(set: Set): void export declare function bufferPassThrough(buf: Buffer): Promise +export declare function bufferWithAsyncBlock(buf: Buffer): Promise + export declare function buildThreadsafeFunctionFromFunction(callback: (arg0: number, arg1: number) => number): void export declare function buildThreadsafeFunctionFromFunctionCalleeHandle(callback: () => void): void diff --git a/examples/napi/src/typed_array.rs b/examples/napi/src/typed_array.rs index 2ccb2e3c..8aef5de1 100644 --- a/examples/napi/src/typed_array.rs +++ b/examples/napi/src/typed_array.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use napi::{bindgen_prelude::*, JsArrayBuffer}; #[napi] @@ -73,6 +75,16 @@ async fn buffer_pass_through(buf: Buffer) -> Result { Ok(buf) } +#[napi] +fn buffer_with_async_block(env: Env, buf: Arc) -> Result> { + let buf_to_dispose = buf.clone(); + AsyncBlockBuilder::with(async move { Ok(buf.len() as u32) }) + .with_dispose(move |_| { + drop(buf_to_dispose); + }) + .build(env) +} + #[napi] async fn array_buffer_pass_through(buf: Uint8Array) -> Result { Ok(buf)