feat(napi): provide reject method in Task trait
Do some cleanup logic if needed
This commit is contained in:
parent
08e5804c3b
commit
9d38689426
4 changed files with 38 additions and 8 deletions
|
@ -93,10 +93,13 @@ unsafe extern "C" fn complete<T: Task>(
|
||||||
let value_ptr = mem::replace(&mut work.value, Ok(mem::MaybeUninit::zeroed()));
|
let value_ptr = mem::replace(&mut work.value, Ok(mem::MaybeUninit::zeroed()));
|
||||||
let deferred = mem::replace(&mut work.deferred, ptr::null_mut());
|
let deferred = mem::replace(&mut work.deferred, ptr::null_mut());
|
||||||
let napi_async_work = mem::replace(&mut work.napi_async_work, ptr::null_mut());
|
let napi_async_work = mem::replace(&mut work.napi_async_work, ptr::null_mut());
|
||||||
let value = value_ptr.and_then(move |v| {
|
let value = match value_ptr {
|
||||||
|
Ok(v) => {
|
||||||
let output = v.assume_init();
|
let output = v.assume_init();
|
||||||
work.inner_task.resolve(Env::from_raw(env), output)
|
work.inner_task.resolve(Env::from_raw(env), output)
|
||||||
});
|
}
|
||||||
|
Err(e) => work.inner_task.reject(Env::from_raw(env), e),
|
||||||
|
};
|
||||||
match check_status!(status).and_then(move |_| value) {
|
match check_status!(status).and_then(move |_| value) {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
let status = sys::napi_resolve_deferred(env, deferred, v.raw());
|
let status = sys::napi_resolve_deferred(env, deferred, v.raw());
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
use crate::js_values::NapiValue;
|
use crate::{js_values::NapiValue, Env, Error, Result};
|
||||||
use crate::{Env, Result};
|
|
||||||
|
|
||||||
pub trait Task: Send {
|
pub trait Task: Send + Sized {
|
||||||
type Output: Send + Sized + 'static;
|
type Output: Send + Sized + 'static;
|
||||||
type JsValue: NapiValue;
|
type JsValue: NapiValue;
|
||||||
|
|
||||||
|
/// Compute logic in libuv thread
|
||||||
fn compute(&mut self) -> Result<Self::Output>;
|
fn compute(&mut self) -> Result<Self::Output>;
|
||||||
|
|
||||||
|
/// Into this method if `compute` return `Ok`
|
||||||
fn resolve(self, env: Env, output: Self::Output) -> Result<Self::JsValue>;
|
fn resolve(self, env: Env, output: Self::Output) -> Result<Self::JsValue>;
|
||||||
|
|
||||||
|
/// Into this method if `compute` return `Err`
|
||||||
|
fn reject(self, _env: Env, err: Error) -> Result<Self::JsValue> {
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,3 +12,14 @@ test('should be able to spawn thread with ref value', async (t) => {
|
||||||
const result = await bindings.testSpawnThreadWithRef(Buffer.from(fixture))
|
const result = await bindings.testSpawnThreadWithRef(Buffer.from(fixture))
|
||||||
t.is(result, fixture.length)
|
t.is(result, fixture.length)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should be able to spawn with error', async (t) => {
|
||||||
|
const fixture = Array.from({ length: 10 }).fill('0').join('')
|
||||||
|
const err = new Error('Unreachable')
|
||||||
|
try {
|
||||||
|
await bindings.testSpawnThreadWithRef(Buffer.from(fixture))
|
||||||
|
throw err
|
||||||
|
} catch (e) {
|
||||||
|
t.not(e, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use napi::{CallContext, Env, JsBuffer, JsBufferValue, JsNumber, JsObject, Ref, Result, Task};
|
use napi::{
|
||||||
|
CallContext, Env, Error, JsBuffer, JsBufferValue, JsNumber, JsObject, Ref, Result, Task,
|
||||||
|
};
|
||||||
|
|
||||||
struct ComputeFib {
|
struct ComputeFib {
|
||||||
n: u32,
|
n: u32,
|
||||||
|
@ -56,6 +58,9 @@ impl Task for CountBufferLength {
|
||||||
type JsValue = JsNumber;
|
type JsValue = JsNumber;
|
||||||
|
|
||||||
fn compute(&mut self) -> Result<Self::Output> {
|
fn compute(&mut self) -> Result<Self::Output> {
|
||||||
|
if self.data.len() == 10 {
|
||||||
|
return Err(Error::from_reason("len can't be 5".to_string()));
|
||||||
|
}
|
||||||
Ok((&self.data).len())
|
Ok((&self.data).len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +68,11 @@ impl Task for CountBufferLength {
|
||||||
self.data.unref(env)?;
|
self.data.unref(env)?;
|
||||||
env.create_uint32(output as _)
|
env.create_uint32(output as _)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reject(self, env: Env, err: Error) -> Result<Self::JsValue> {
|
||||||
|
self.data.unref(env)?;
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[js_function(1)]
|
#[js_function(1)]
|
||||||
|
|
Loading…
Reference in a new issue