Skip to content

Commit 4b8918b

Browse files
romandevmhdawson
authored andcommitted
Add resource parameters to AsyncWorker constructor
This change is initiated from #140 (comment). PR-URL: #253 Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Nicola Del Gobbo <[email protected]>
1 parent 1ecf7c1 commit 4b8918b

File tree

4 files changed

+134
-22
lines changed

4 files changed

+134
-22
lines changed

napi-inl.h

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,21 +3079,51 @@ inline Value EscapableHandleScope::Escape(napi_value escapee) {
30793079
////////////////////////////////////////////////////////////////////////////////
30803080

30813081
inline AsyncWorker::AsyncWorker(const Function& callback)
3082-
: AsyncWorker(Object::New(callback.Env()), callback) {
3082+
: AsyncWorker(callback, "generic") {
30833083
}
30843084

3085-
inline AsyncWorker::AsyncWorker(const Object& receiver, const Function& callback)
3085+
inline AsyncWorker::AsyncWorker(const Function& callback,
3086+
const char* resource_name)
3087+
: AsyncWorker(callback, resource_name, Object::New(callback.Env())) {
3088+
}
3089+
3090+
inline AsyncWorker::AsyncWorker(const Function& callback,
3091+
const char* resource_name,
3092+
const Object& resource)
3093+
: AsyncWorker(Object::New(callback.Env()),
3094+
callback,
3095+
resource_name,
3096+
resource) {
3097+
}
3098+
3099+
inline AsyncWorker::AsyncWorker(const Object& receiver,
3100+
const Function& callback)
3101+
: AsyncWorker(receiver, callback, "generic") {
3102+
}
3103+
3104+
inline AsyncWorker::AsyncWorker(const Object& receiver,
3105+
const Function& callback,
3106+
const char* resource_name)
3107+
: AsyncWorker(receiver,
3108+
callback,
3109+
resource_name,
3110+
Object::New(callback.Env())) {
3111+
}
3112+
3113+
inline AsyncWorker::AsyncWorker(const Object& receiver,
3114+
const Function& callback,
3115+
const char* resource_name,
3116+
const Object& resource)
30863117
: _env(callback.Env()),
30873118
_receiver(Napi::Persistent(receiver)),
30883119
_callback(Napi::Persistent(callback)) {
3089-
30903120
napi_value resource_id;
30913121
napi_status status = napi_create_string_latin1(
3092-
_env, "generic", NAPI_AUTO_LENGTH, &resource_id);
3122+
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
30933123
NAPI_THROW_IF_FAILED(_env, status);
30943124

3095-
status = napi_create_async_work(
3096-
_env, nullptr, resource_id, OnExecute, OnWorkComplete, this, &_work);
3125+
status = napi_create_async_work(_env, resource, resource_id, OnExecute,
3126+
OnWorkComplete, this, &_work);
30973127
NAPI_THROW_IF_FAILED(_env, status);
30983128
}
30993129

napi.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,20 @@ namespace Napi {
15151515

15161516
protected:
15171517
explicit AsyncWorker(const Function& callback);
1518-
explicit AsyncWorker(const Object& receiver, const Function& callback);
1518+
explicit AsyncWorker(const Function& callback,
1519+
const char* resource_name);
1520+
explicit AsyncWorker(const Function& callback,
1521+
const char* resource_name,
1522+
const Object& resource);
1523+
explicit AsyncWorker(const Object& receiver,
1524+
const Function& callback);
1525+
explicit AsyncWorker(const Object& receiver,
1526+
const Function& callback,
1527+
const char* resource_name);
1528+
explicit AsyncWorker(const Object& receiver,
1529+
const Function& callback,
1530+
const char* resource_name,
1531+
const Object& resource);
15191532

15201533
virtual void Execute() = 0;
15211534
virtual void OnOK();

test/asyncworker.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ class TestWorker : public AsyncWorker {
66
public:
77
static void DoWork(const CallbackInfo& info) {
88
bool succeed = info[0].As<Boolean>();
9-
Function cb = info[1].As<Function>();
10-
Value data = info[2];
9+
Object resource = info[1].As<Object>();
10+
Function cb = info[2].As<Function>();
11+
Value data = info[3];
1112

12-
TestWorker* worker = new TestWorker(cb);
13+
TestWorker* worker = new TestWorker(cb, "TestResource", resource);
1314
worker->Receiver().Set("data", data);
1415
worker->_succeed = succeed;
1516
worker->Queue();
@@ -23,7 +24,8 @@ class TestWorker : public AsyncWorker {
2324
}
2425

2526
private:
26-
TestWorker(Function cb) : AsyncWorker(cb) {}
27+
TestWorker(Function cb, const char* resource_name, const Object& resource)
28+
: AsyncWorker(cb, resource_name, resource) {}
2729
bool _succeed;
2830
};
2931

test/asyncworker.js

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,88 @@
11
'use strict';
22
const buildType = process.config.target_defaults.default_configuration;
33
const assert = require('assert');
4+
const async_hooks = require('async_hooks');
5+
const common = require('./common');
46

57
test(require(`./build/${buildType}/binding.node`));
68
test(require(`./build/${buildType}/binding_noexcept.node`));
79

10+
function installAsyncHooksForTest() {
11+
return new Promise((resolve, reject) => {
12+
let id;
13+
const events = [];
14+
const hook = async_hooks.createHook({
15+
init(asyncId, type, triggerAsyncId, resource) {
16+
if (id === undefined && type === 'TestResource') {
17+
id = asyncId;
18+
events.push({ eventName: 'init', type, triggerAsyncId, resource });
19+
}
20+
},
21+
before(asyncId) {
22+
if (asyncId === id) {
23+
events.push({ eventName: 'before' });
24+
}
25+
},
26+
after(asyncId) {
27+
if (asyncId === id) {
28+
events.push({ eventName: 'after' });
29+
}
30+
},
31+
destroy(asyncId) {
32+
if (asyncId === id) {
33+
events.push({ eventName: 'destroy' });
34+
hook.disable();
35+
resolve(events);
36+
}
37+
}
38+
}).enable();
39+
});
40+
}
41+
842
function test(binding) {
9-
binding.asyncworker.doWork(true, function (e) {
10-
assert.strictEqual(typeof e, 'undefined');
11-
assert.strictEqual(typeof this, 'object');
12-
assert.strictEqual(this.data, 'test data');
13-
}, 'test data');
43+
{
44+
const hooks = installAsyncHooksForTest();
45+
const triggerAsyncId = async_hooks.executionAsyncId();
46+
binding.asyncworker.doWork(true, { foo: 'foo' }, function (e) {
47+
assert.strictEqual(typeof e, 'undefined');
48+
assert.strictEqual(typeof this, 'object');
49+
assert.strictEqual(this.data, 'test data');
50+
}, 'test data');
51+
52+
hooks.then(actual => {
53+
assert.deepStrictEqual(actual, [
54+
{ eventName: 'init',
55+
type: 'TestResource',
56+
triggerAsyncId: triggerAsyncId,
57+
resource: { foo: 'foo' } },
58+
{ eventName: 'before' },
59+
{ eventName: 'after' },
60+
{ eventName: 'destroy' }
61+
]);
62+
}).catch(common.mustNotCall());
63+
}
64+
65+
{
66+
const hooks = installAsyncHooksForTest();
67+
const triggerAsyncId = async_hooks.executionAsyncId();
68+
69+
binding.asyncworker.doWork(false, { foo: 'foo' }, function (e) {
70+
assert.ok(e instanceof Error);
71+
assert.strictEqual(e.message, 'test error');
72+
assert.strictEqual(typeof this, 'object');
73+
assert.strictEqual(this.data, 'test data');
74+
}, 'test data');
1475

15-
binding.asyncworker.doWork(false, function (e) {
16-
assert.ok(e instanceof Error);
17-
assert.strictEqual(e.message, 'test error');
18-
assert.strictEqual(typeof this, 'object');
19-
assert.strictEqual(this.data, 'test data');
20-
}, 'test data');
76+
hooks.then(actual => {
77+
assert.deepStrictEqual(actual, [
78+
{ eventName: 'init',
79+
type: 'TestResource',
80+
triggerAsyncId: triggerAsyncId,
81+
resource: { foo: 'foo' } },
82+
{ eventName: 'before' },
83+
{ eventName: 'after' },
84+
{ eventName: 'destroy' }
85+
]);
86+
}).catch(common.mustNotCall());
87+
}
2188
}

0 commit comments

Comments
 (0)